форматирование длинных чисел в виде строк в Python - PullRequest
25 голосов
/ 23 февраля 2009

Что является простым способом в Python для форматирования целых чисел в строки, представляющие тысячи с K и миллионы с M и оставляющие после запятой всего пару цифр?

Я хотел бы показать 7436313 как 7,44M и 2345 как 2,34K.

Есть ли какой-либо оператор форматирования строки% для этого? Или это можно сделать только путем фактического деления на 1000 в цикле и построения строки результата шаг за шагом?

Ответы [ 8 ]

43 голосов
/ 24 февраля 2009

Я не думаю, что есть встроенная функция, которая делает это. Вы должны будете катиться самостоятельно, например ::10000

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'
15 голосов
/ 23 августа 2017

Эта версия не страдает от ошибки в предыдущих ответах, где 999,999 дает 1000,0K Это также позволяет только 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])

Вывод выглядит так:

>>> human_format(999999)
'1M'
>>> human_format(999499)
'999K'
>>> human_format(9994)
'9.99K'
>>> human_format(9900)
'9.9K'
>>> human_format(6543165413)
'6.54B'
3 голосов
/ 21 апреля 2018

Переменная точность и нет ошибки 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(round(num, round_to), round_to, ['', 'K', 'M', 'G', 'T', 'P'][magnitude])
3 голосов
/ 24 апреля 2017

Мне нужна была эта функция сегодня, немного обновил принятый ответ для людей с 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'

Изменить: учитывая комментарии, вы можете изменить на round(num/1000.0)

2 голосов
/ 03 августа 2017

Более "математическим" решением является использование 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])

Тесты:

>>> human_format(123456)
'123.46K'
>>> human_format(123456789)
'123.46M'
>>> human_format(1234567890)
'1.23G'
0 голосов
/ 24 февраля 2009

Я не знаю ни одной встроенной возможности, подобной этой, но вот пара потоков списка, которые могут помочь:

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

0 голосов
/ 24 февраля 2009

Я не думаю, что для этого есть операторы формата, но вы можете просто разделить на 1000, пока результат не станет между 1 и 999, а затем использовать строку формата для 2 цифр после запятой. Единица измерения - это один символ (или, возможно, небольшая строка) в большинстве случаев, который можно сохранить в строке или массиве и повторять его после каждого деления.

0 голосов
/ 24 февраля 2009

Нет оператора форматирования строки, в соответствии с документами . Я никогда не слышал о таких вещах, так что, возможно, вам придется свернуть свои собственные, как вы предлагаете.

...