Given a set of integers (eg {1000000, 20000000, 1234000, 1200000}
), I want to apply to all of them a function such that:
In other words, I want to strip as many zeros as possible without losing any information other than absolute magnitude, so the set would become {1000, 20000, 1234, 1200}
Is there a term for this operation and is there an efficient Python function, or should I just quickly code this?
Edit: This solution is not a duplicate because it deals with singular numbers - in my case, the number of zeros depends on the particular set.
Edit 2: Green Cloak Guy provided a solution for my exact requirements, and Illmora one that does what I should have actually conceptualized in the first place.
Looking at your requirements, what you are after can be easily done by dividing each input number by the GCD (Greatest Common Denominator) of all the input numbers.
#!/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=',')
With your input numbers, it produces this result:
500,10000,617,600
Because of the properties of the GCD, the output is guaranteed to be the lowest possible integer that still maintains the relative proportions between each number.
Given all you care about here is decreasing magnitude, have you considered just representing your numbers as Decimal
s and then printing them in scientific notation?
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'}
If that's not reasonable for your use case, then another thing you can do is essentially determine the maximum magnitude you can reduce by, and then reduce by that much. For magnitudes of 10, this is fairly simple and you can use strings to do it:
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
For nonstandard magnitudes (eg magnitudes of 3), you'd need to get more creative and come up with a way to efficiently figure out the largest magnitude you can divide by. My example above takes a shortcut here by checking how many digits disappear when we cut out the trailing zeroes (which is equivalent to checking the largest exponent of 10 that can be integer-divided into the number). Since python doesn't have a built-in way to print in bases that aren't 2, 8, 10, or 16, you'll have to figure out your own solution.
Don't kwow if there's a more efficient way. I would use:
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
Results:
intgrs = (1000000, 20000000, 1234000, 1200000)
print(reduce(intgrs))
It will return a numpy array with the following values: [1000 20000 1234 1200]
Not so gentle, but it works.
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]
Just in case you don't worry about the ordering of the set elements.
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}
not have nested loop or two loop which contain some work
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)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.