简体   繁体   English

在 python 中将长数字格式化为字符串

[英]formatting long numbers as strings in python

What is an easy way in Python to format integers into strings representing thousands with K, and millions with M, and leaving just couple digits after comma? Python 中有什么简单的方法可以将整数格式化为字符串,用 K 表示千位,用 M 表示百万位,逗号后只留下几个数字?

I'd like to show 7436313 as 7.44M, and 2345 as 2,34K.我想将 7436313 显示为 7.44M,将 2345 显示为 2,34K。

Is there some % string formatting operator available for that?是否有一些可用的 % 字符串格式化运算符? Or that could be done only by actually dividing by 1000 in a loop and constructing result string step by step?或者只能通过在循环中实际除以 1000 并逐步构造结果字符串来完成?

I don't think there's a built-in function that does that.我不认为有一个内置函数可以做到这一点。 You'll have to roll your own, eg:你必须自己动手,例如:

def human_format(num):
    magnitude = 0
    while abs(num) >= 1000:
        magnitude += 1
        num /= 1000.0
    # add more suffixes if you need them
    return '%.2f%s' % (num, ['', 'K', 'M', 'G', 'T', 'P'][magnitude])

print('the answer is %s' % human_format(7436313))  # prints 'the answer is 7.44M'

This version does not suffer from the bug in the previous answers where 999,999 gives you 1000.0K.此版本不会受到先前答案中 999,999 为您提供 1000.0K 的错误的影响。 It also only allows 3 significant figures and eliminates trailing 0's.它还只允许 3 个有效数字并消除尾随的 0。

def human_format(num):
    num = float('{:.3g}'.format(num))
    magnitude = 0
    while abs(num) >= 1000:
        magnitude += 1
        num /= 1000.0
    return '{}{}'.format('{:f}'.format(num).rstrip('0').rstrip('.'), ['', 'K', 'M', 'B', 'T'][magnitude])

The output looks like:输出看起来像:

>>> human_format(999999)
'1M'
>>> human_format(999499)
'999K'
>>> human_format(9994)
'9.99K'
>>> human_format(9900)
'9.9K'
>>> human_format(6543165413)
'6.54B'

A more "math-y" solution is to use math.log :更“数学”的解决方案是使用math.log

from math import log, floor


def human_format(number):
    units = ['', 'K', 'M', 'G', 'T', 'P']
    k = 1000.0
    magnitude = int(floor(log(number, k)))
    return '%.2f%s' % (number / k**magnitude, units[magnitude])

Tests:测试:

>>> human_format(123456)
'123.46K'
>>> human_format(123456789)
'123.46M'
>>> human_format(1234567890)
'1.23G'

I needed this function today, refreshed the accepted answer a bit for people with Python >= 3.6:我今天需要这个函数,为 Python >= 3.6 的人更新了一点接受的答案:

def human_format(num, precision=2, suffixes=['', 'K', 'M', 'G', 'T', 'P']):
    m = sum([abs(num/1000.0**x) >= 1 for x in range(1, len(suffixes))])
    return f'{num/1000.0**m:.{precision}f}{suffixes[m]}'

print('the answer is %s' % human_format(7454538))  # prints 'the answer is 7.45M'

Edit: given the comments, you might want to change to round(num/1000.0)编辑:根据评论,您可能希望更改为round(num/1000.0)

Variable precision and no 999999 bug:可变精度且没有 999999 错误:

def human_format(num, round_to=2):
    magnitude = 0
    while abs(num) >= 1000:
        magnitude += 1
        num = round(num / 1000.0, round_to)
    return '{:.{}f}{}'.format(num, round_to, ['', 'K', 'M', 'G', 'T', 'P'][magnitude])

I was kind of confused by some of the stuff that other people showed, so I made the below code.我被其他人展示的一些东西弄糊涂了,所以我做了下面的代码。 It rounds to the second decimal point, ex.它四舍五入到第二个小数点,例如。 '23.56 Billion', but you can change what decimal place it rounds to by replacing the two '100.0's in the last line with a larger or smaller number, ex. “235.6 亿”,但您可以通过将最后一行中的两个“100.0”替换为更大或更小的数字来更改其舍入到的小数位数,例如。 '10.0' rounds to one decimal point and '1000.0' rounds to three decimal points. “10.0”四舍五入到一位小数,“1000.0”四舍五入到三个小数点。 Also, using this code, it always rounds down from what it actually is.此外,使用此代码,它总是从实际情况四舍五入。 You can change this if you like, by replacing 'floor' with 'ceil' or 'round'.如果您愿意,可以通过将“地板”替换为“天花板”或“圆形”来更改此设置。

#make the dictionary to store what to put after the result (ex. 'Billion'). You can go further with this then I did, or to wherever you wish. 
#import the desired rounding mechanism. You will not need to do this for round. 
from math import floor
magnitudeDict={0:'', 1:'Thousand', 2:'Million', 3:'Billion', 4:'Trillion', 5:'Quadrillion', 6:'Quintillion', 7:'Sextillion', 8:'Septillion', 9:'Octillion', 10:'Nonillion', 11:'Decillion'}
def simplify(num):
    num=floor(num)
    magnitude=0
    while num>=1000.0:
        magnitude+=1
        num=num/1000.0
    return(f'{floor(num*100.0)/100.0} {magnitudeDict[magnitude]}')

The 'f' before the string in the last line is to let python know you are formatting it.最后一行字符串前的 'f' 是让 python 知道你正在格式化它。 The result from running print(simplify(34867123012.13)) is this:运行 print(simplify(34867123012.13)) 的结果是这样的:

34.86 Billion

Please let me know if you have questions!如果您有任何问题,请告诉我! Thanks, Angus谢谢,安格斯

I had the same need.我有同样的需求。 And if anyone comes on this topic, I found a lib to do so: https://github.com/azaitsev/millify如果有人谈到这个话题,我找到了一个库来这样做: https : //github.com/azaitsev/millify

Hope it helps :)希望能帮助到你 :)

No String Formatting Operator, according to the docs . 根据文档,没有字符串格式操作符。 I've never heard of such a thing, so you may have to roll your own, as you suggest.我从来没有听说过这样的事情,所以你可能不得不按照你的建议自己动手。

I don't think there are format operators for that, but you can simply divide by 1000 until the result is between 1 and 999 and then use a format string for 2 digits after comma.我认为没有格式运算符,但您可以简单地除以 1000,直到结果介于 1 和 999 之间,然后在逗号后使用 2 位格式字符串。 Unit is a single character (or perhaps a small string) in most cases, which you can store in a string or array and iterate through it after each divide.在大多数情况下,单位是单个字符(或者可能是一个小字符串),您可以将其存储在字符串或数组中,并在每次除法后遍历它。

I don't know of any built-in capability like this, but here are a couple of list threads that may help:我不知道任何像这样的内置功能,但这里有几个列表线程可能会有所帮助:

http://coding.derkeiler.com/Archive/Python/comp.lang.python/2005-09/msg03327.html http://mail.python.org/pipermail/python-list/2008-August/503417.html http://coding.derkeiler.com/Archive/Python/comp.lang.python/2005-09/msg03327.html http://mail.python.org/pipermail/python-list/2008-August/503417.html

Numerize library is good.数字图书馆很好。

from numerize import numerize
a = numerize.numerize(1000)
print(a)
1k

Thanks @tdy for pointing this,感谢@tdy 指出这一点,

a = numerize.numerize(999999) 
print(a)  # 1000K 
1000K

Based on the comments here, I made an improved code for that.根据这里的评论,我为此做了一个改进的代码。 It is a little bit longer but gives solutions for more cases including small numbers (m,u,n,p).它有点长,但为更多情况提供了解决方案,包括小数(m,u,n,p)。

Hope it will be helpful for someone希望对某人有所帮助

# print number in a readable format.
# default is up to 3 decimal digits and can be changed
# works on numbers in the range of 1e-15 to 1e 1e15 include negatives numbers
# can force the number to a specific magnitude unit
def human_format(num:float, force=None, ndigits=3):
    perfixes = ('p', 'n', 'u', 'm', '', 'K', 'M', 'G', 'T')
    one_index = perfixes.index('')
    if force:
        if force in perfixes:
            index = perfixes.index(force)
            magnitude = 3*(index - one_index)
            num = num/(10**magnitude)
        else:
            raise ValueError('force value not supported.')
    else:
        div_sum = 0
        if(abs(num) >= 1000):
            while abs(num) >= 1000:
                div_sum += 1
                num /= 1000
        else:
            while abs(num) <= 1:
                div_sum -= 1
                num *= 1000
        temp = round(num, ndigits) if ndigits else num
        if temp < 1000:
            num = temp 
        else:
            num = 1
            div_sum += 1
        index = one_index + div_sum
    return str(num).rstrip('0').rstrip('.') + perfixes[index]

tests from here and some more从这里开始的测试以及更多

# some tests
print(human_format(999)              ,' = '         , '999') 
print(human_format(999.999)          ,' = '         , '999.999') 
print(human_format(999.9999)         ,' = '         , '1K')  
print(human_format(999999)           ,' = '         , '999.999K')   
print(human_format(999499)           ,' = '         , '999.499K')   
print(human_format(9994)             ,' = '         , '9.994K')   
print(human_format(9900)             ,' = '         , '9.9K')   
print(human_format(6543165413)       ,' = '         , '6.543G')  
print(human_format(46780.9)          ,' = '         , '46.781K')  
print(human_format(0.001)            ,' = '         , '1m')   
print(human_format(0.000000999999)   ,' = '         , '999.999n')  
print(human_format(1.00394200)       ,' = '         , '1.004')   
print(human_format(0.0999)           ,' = '         , '99.9m')  
print(human_format(0.00000000999999) ,' = '         , '10n') 
print(human_format(0.0000000099995)  ,' = '         , '9.999n')  
print(human_format(0.000000009999)   ,' = '         , '9.999n') 
print(human_format(999999            ,ndigits=2)    ,' = '           , '1M')   
print(human_format(9994              ,force='')     ,' = '           , '9994K')   
print(human_format(6543165413        ,ndigits=5)    ,' = '           , '6.54317G')  
print(human_format(6543165413        ,ndigits=None) ,' = '           , '6.543165413G')  
print(human_format(7436313           ,ndigits=2)    ,' = '           , '7.44M')   
print(human_format(2344              ,ndigits=2)    ,' = '           , '2.34K')
print(human_format(34867123012.13    ,ndigits=2)    ,' = '           , '34.87G')   
def human_format(value):
   num = value
   magnitude = 0
   while abs(num) >= 1000:
      magnitude += 1
      num /= 1000.0
   result = round(value / (1000**magnitude),3)
   return '{}{}'.format(result, ['', 'K', 'M', 'B', 'T'][magnitude])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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