如何对python小数进行区域设置格式并保持其精度? [英] How can I locale-format a python Decimal and preserve its precision?
问题描述
如何使用语言环境格式化十进制
?
How can I format a Decimal
using a locale?
为了举例说明,我试图定义一个函数 f
,使其在美国英语语言环境中:
To describe by examples, I'm trying to define a function f
such that in the US English locale:
-
f(十进制('5000.00'))=='5,000.00'
f(十进制('1234567.000000'))=='1,234,567.000000'
一些不起作用的东西:
-
f = str
不使用语言环境;f(Decimal('5000.00'))=='5000.00'
f = lambda d:locale.format('%f',d)
不保留小数精度; f(Decimal('5000.00'))=='5000.000000'
f = lambda d:locale.format('%.2f',d)
使用固定精度,这不是我想要的; f(Decimal('1234567.000000'))=='1234567.00'
f = lambda d: locale.format('%.2f', d)
uses a fixed precision, which isn't what I'm after; f(Decimal('1234567.000000')) == '1234567.00'
推荐答案
通读 Decimal
模块的源代码, Decimal .__ format __
提供完整的
Reading through the source for the decimal
module, Decimal.__format__
provides full PEP 3101 support, and all you have to do is select the correct presentation type. In this case, you want the :n
type. According PEP 3101 spec, this :n
has the following properties:
'n'-数字.这与'g'相同,但它使用的是当前的语言环境设置以插入适当的数字分隔符.
'n' - Number. This is the same as 'g', except that it uses the current locale setting to insert the appropriate number separator characters.
这比其他答案更简单,并且避免了我原来的答案中的浮点精度问题(保留在下面):
This is simpler than other answers, and avoids the float precision issue in my original answer (preserved below):
>>> import locale
>>> from decimal import Decimal
>>>
>>> def f(d):
... return '{0:n}'.format(d)
...
>>>
>>> locale.setlocale(locale.LC_ALL, 'en_us')
'en_us'
>>> print f(Decimal('5000.00'))
5,000.00
>>> print f(Decimal('1234567.000000'))
1,234,567.000000
>>> print f(Decimal('123456700000000.123'))
123,456,700,000,000.123
>>> locale.setlocale(locale.LC_ALL, 'no_no')
'no_no'
>>> print f(Decimal('5000.00'))
5.000,00
>>> print f(Decimal('1234567.000000'))
1.234.567,000000
>>> print f(Decimal('123456700000000.123'))
123.456.700.000.000,123
原始错误答案
您可以告诉格式字符串使用与小数本身一样多的精度,并使用语言环境格式化程序:
Original, wrong answer
You can just tell the format string to use as much precision as is included in the decimal itself and use the locale formatter:
def locale_format(d):
return locale.format('%%0.%df' % (-d.as_tuple().exponent), d, grouping=True)
请注意,如果您拥有一个与实数相对应的小数,则可以使用,但是如果小数是 NaN
或 + Inf
或其他形式,则无法正常工作像那样.如果您的输入中有这些可能性,则需要使用format方法进行解释.
Note that works if you've got a decimal which corresponds to a real number, but doesn't work correctly if the decimal is NaN
or +Inf
or something like that. If those are possibilities in your input, you'd need to account for them in the format method.
>>> locale.setlocale(locale.LC_ALL, 'en_US')
'en_US'
>>> locale_format(Decimal('1234567.000000'))
'1,234,567.000000'
>>> locale_format(Decimal('5000.00'))
'5,000.00'
>>> locale.setlocale(locale.LC_ALL, 'no_no')
'no_no'
>>> locale_format(Decimal('1234567.000000'))
'1.234.567,000000'
>>> locale_format(Decimal('5000.00'))
'5.000,00'
>>> locale_format(Decimal('NaN'))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in locale_format
TypeError: bad operand type for unary -: 'str'
这篇关于如何对python小数进行区域设置格式并保持其精度?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!