Как убрать целые числа конечных нулей - PullRequest
1 голос
/ 09 октября 2019

Учитывая набор целых чисел (например, {1000000, 20000000, 1234000, 1200000}), я хочу применить ко всем из них такую ​​функцию, чтобы:

  1. величина числа была уменьшена настолько, насколько это возможно
  2. все числа остаются целыми числами
  3. их относительные пропорции остаются постоянными

Другими словами, я хочу убрать как можно больше нулей, не теряя никакой информации, кроме абсолютной величины,таким образом, набор станет {1000, 20000, 1234, 1200}

Есть ли термин для этой операции и есть ли эффективная функция Python, или я должен просто быстро написать это?

Редактировать: Это решение не является дубликатом, поскольку оно имеет дело с единичными числами - в моем случае число нулей зависит от конкретного набора.

Редактировать 2: Зеленый плащ Парень предоставил решение для моих точных требований, и Illmora, который делает то, что я должен был на самом деле концептуализировать в первую очередь.

Ответы [ 6 ]

3 голосов
/ 09 октября 2019

Глядя на ваши требования, то, что вам нужно, можно легко сделать, разделив каждое входное число на GCD (наибольший общий знаменатель) всех входных чисел.

#!/usr/bin/env python3

import math
from functools import reduce

numbers = [1000000, 20000000, 1234000, 1200000]

# Find the greatest common denominator
gcd = reduce(lambda x,y: math.gcd(x,y), numbers)

# Divide each number by the GCD
minimum_numbers = map(lambda x: int(x/gcd), numbers)

print(*minimum_numbers, sep=',')

С вашими входными числами этодает такой результат:

500,10000,617,600

Из-за свойств GCD выход гарантированно будет наименьшим возможным целым числом, которое все еще поддерживает относительные пропорции между каждым числом.

2 голосов
/ 09 октября 2019

Учитывая все, что вас волнует, это уменьшение величины, рассматривали ли вы просто представление своих чисел как Decimal с и затем печать их в научной записи?

from decimal import Decimal

nums = {Decimal(1000000), Decimal(20000000), Decimal(1234000), Decimal(1200000)}
print({str(num.normalize()) for num in nums})
# {'1E+6', '1.2E+6', '2E+7', '1.234E+6'}

Если это нецелесообразно дляваш вариант использования, тогда еще одна вещь, которую вы можете сделать, это по существу определить максимальную величину, на которую вы можете уменьшить, а затем уменьшить на столько. Для величин 10 это довольно просто, и вы можете использовать строки для этого:

nums = {1000000, 20000000, 1234000, 1200000}
div_factor = 10 ** min(len(str(num)) - len(str(num).rstrip('0')) for num in nums)
reduced_nums = {num / div_factor for num in nums}
# {1000.0, 1234.0, 20000.0, 1200.0}
# you can use integer division `//` instead of true division `/` if you want

Для нестандартных величин (например, величин 3) вам нужно проявить больше творчества и придуматьспособ эффективно определить наибольшую величину, которую вы можете разделить. В моем примере, приведенном выше, используется ярлык, проверяющий, сколько цифр исчезает, когда мы вырезаем конечные нули (что эквивалентно проверке наибольшего показателя 10, который можно разделить на целое число). Поскольку в python нет встроенного способа печати на базах, не равных 2, 8, 10 или 16, вам придется найти собственное решение.

0 голосов
/ 11 октября 2019

не имеют вложенного цикла или двух циклов, содержащих некоторую работу

from numpy import multiply

intgr = [1000000, 20000000, 1234000, 1200000]
total = str( sum(intgr) )
mgntd = 10 ** ( len(total) - len(total.rstrip('0') ))
reslt = multiply(intgr, [1/mgntd]*len(intgr)).astype(int)
0 голосов
/ 09 октября 2019

На всякий случай, если вас не беспокоит порядок элементов набора.

 sets = {1000000, 20000000, 1234000, 1200000}
 max = max([len("".join(map(str, str(i))).rstrip('0')) for i in sets])
 new_set = {int(str(i)[:max]) for i in sets}  # gives {1000, 1234, 1200, 2000}
0 голосов
/ 09 октября 2019

Не так нежно, но работает.

def trim_zeros(nums):
  while 1:
    for i in nums:
        if str(i)[-1] != "0":
            return(nums)                 
    nums=[int(i/10) for i in nums]
0 голосов
/ 09 октября 2019

Не знаю, есть ли более эффективный способ. Я бы использовал:

import numpy as np

def reduce(array):

    mult = [0.1]*len(array)

    while all(item%10 == 0 for item in array):
        array = np.multiply(array, mult)

    return array

Результаты:

intgrs = (1000000, 20000000, 1234000, 1200000)
print(reduce(intgrs))

Будет возвращен массив значений со следующими значениями: [1000 20000 1234 1200]

...