简体   繁体   中英

How to strip integers of trailing zeros

Given a set of integers (eg {1000000, 20000000, 1234000, 1200000} ), I want to apply to all of them a function such that:

  1. the magnitude of a number is lowered as far as possible
  2. all numbers remain integers
  3. their relative proportions remain constant

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM