Formato de moneda en Python

156

Estoy buscando formatear un número como 188518982.18 a £ 188,518,982.18 usando Python.

¿Cómo puedo hacer esto?

CarrilesHijo
fuente
Hizo un excelente comentario en un comentario a continuación, @RailsSon: desea imprimir £ s para mostrar una moneda específica, pero emplee esa pantalla usando una expresión japonesa para números financieros. Me resulta extraño que su solicitud no se haya implementado en el idioma al desacoplar el localeuso del módulo del valor de la moneda y las propiedades de visualización de esa moneda.
Droogans

Respuestas:

212

Ver el módulo de configuración regional .

Esto hace el formato de moneda (y fecha).

>>> import locale
>>> locale.setlocale( locale.LC_ALL, '' )
'English_United States.1252'
>>> locale.currency( 188518982.18 )
'$188518982.18'
>>> locale.currency( 188518982.18, grouping=True )
'$188,518,982.18'
S.Lott
fuente
15
¿Cómo formatearía correctamente una moneda no nativa, digamos que estoy mostrando un costo en libras esterlinas para un informe en japonés?
SingleNegationElimination
2
@TokenMacGuy: Esa es una pregunta capciosa. Informe japonés significa reglas japonesas de coma y coma decimal, pero símbolo de moneda libra esterlina, no es trivialmente compatible con Locale. Debe crear una definición de configuración regional personalizada.
S.Lott el
si el número de donante es negativo, devuelve el valor entre "()" ¿por qué?
panchicore
66
Esto todavía no funcionó para mí, pero lo cambié locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')y funcionó perfectamente.
Furbeenator
2
@panchicore la notación para números negativos como se indica entre paréntesis es una práctica común en el mundo de la contabilidad. Pruébelo en oocalc o excel, y formatee los números al tipo de contabilidad.
Droogans
94

Nuevo en 2.7

>>> '{:20,.2f}'.format(18446744073709551616.0)
'18,446,744,073,709,551,616.00'

http://docs.python.org/dev/whatsnew/2.7.html#pep-0378

nate c
fuente
66
Eso está bien, pero realmente no responde la pregunta, ya que la solución solicitada incluiría un símbolo de moneda, y también está codificando el número de dígitos después del decimal, que es específico de la localidad. Hay muchas más razones para usar la respuesta de configuración regional aceptada si no solo desea la colocación de comas.
mrooney
66
@mrooney También hay muchas razones para no usar la respuesta local aceptada, como no importar un módulo completo.
Josh
1
@ Josh, "desde la moneda de importación local".
Andrew H
55
@mrooney: puede simplemente hacer: '$ {: 0, .2f}'. formato (184467616.1), y ahora tiene el símbolo
triunenature
@triunenature que resultaría a $ 123,456.78veces sin embargo. Editar: markdown elimina los espacios adicionales, pretende que hay más entre $ y los números
CyberJacob
48

No estoy seguro de por qué no se menciona más en línea (o en este hilo), pero el paquete Babel (y las utilidades de Django) de los chicos de Edgewall es increíble para el formato de moneda (y muchas otras tareas de i18n). Es bueno porque no sufre la necesidad de hacer todo a nivel mundial, como el módulo central de Python.

El ejemplo que dio el OP sería simplemente:

>>> import babel.numbers
>>> import decimal
>>> babel.numbers.format_currency( decimal.Decimal( "188518982.18" ), "GBP" )
£188,518,982.18
glenc
fuente
2
Nota muy tardía: al probar esto, no parece formatear de manera inteligente la moneda, ya que simplemente pega el símbolo apropiado antes de la cantidad (formateada en lo que parece ser la configuración regional que ha establecido, lo cual es razonable), independientemente de si esa moneda realmente usa su símbolo como prefijo.
kungphu
@kungphu ¿Qué quieres decir? Ver babel.pocoo.org/en/latest/api/…
Julian
1
@Julian Parece que el localeargumento format_currencypuede usarse para abordar esto, pero o eso no estaba en el documento hace cuatro años (cuando escribí ese comentario) o simplemente probé el código de esta respuesta tal como está sin consultar el documento.
kungphu
1
@kungphu Gotcha. Debo haber estado prestando atención a la edad de esta publicación ayer. El cambio de documentación / función parece muy probable. ¡Salud!
Juliano
32

Esta es una publicación antigua, pero acabo de implementar la siguiente solución que:

  • No requiere módulos externos.
  • No requiere crear una nueva función
  • Se puede hacer en línea.
  • Maneja múltiples variables
  • Maneja cantidades negativas en dólares

Código:

num1 = 4153.53
num2 = -23159.398598

print 'This: ${:0,.0f} and this: ${:0,.2f}'.format(num1, num2).replace('$-','-$')

Salida:

This: $4,154 and this: -$23,159.40

Y para el póster original, obviamente, simplemente cambie $por£

elPastor
fuente
mi formato necesitaba algo de personalización, pero está bien porque pude hacerlo con esta solución.
DonkeyKong
10
¡Buena idea! Con Python 3.6 y f-strings, se ve aún más hermoso:print(f'Value is: ${value:,.2f}'.replace('$-', '-$'))
Timo Saloranta
16

Mi configuración regional parecía incompleta, así que también miré más allá de esta respuesta SO y encontré:

http://docs.python.org/library/decimal.html#recipes

Independiente del sistema operativo

Solo quería compartir aquí.

usuario37986
fuente
¿Pero a dónde llamamos def moneyfmt(value, places=2, curr='', sep=',', dp='.', pos='', neg='-', trailneg='')?
Roel
9

Si está utilizando OSX y aún no ha configurado el módulo de configuración regional, esta primera respuesta no funcionará, recibirá el siguiente error:

Traceback (most recent call last):File "<stdin>", line 1, in <module> File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/locale.py", line 221, in currency
raise ValueError("Currency formatting is not possible using "ValueError: Currency formatting is not possible using the 'C' locale.

Para remediar esto, deberá utilizar lo siguiente:

locale.setlocale(locale.LC_ALL, 'en_US')
simoes
fuente
2
locale.setlocale (locale.LC_ALL, 'en_US.UTF-8') hace por mí
alexblum
9

"{:0,.2f}".format(float(your_numeric_value))en Python 3 hace el trabajo; da algo como una de las siguientes líneas:

10,938.29
10,899.00
10,898.99
2,328.99
Eugene Gr. Philippov
fuente
6

Si fuera usted, usaría BABEL: http://babel.pocoo.org/en/latest/index.html

from babel.numbers import format_decimal


format_decimal(188518982.18, locale='en_US')
Carlos
fuente
1
El módulo de configuración regional de Python no funcionó para mí (cualquier configuración regional que configuré, se quejó), pero requerir babel y usar esta función es bueno. Vale la pena echar un vistazo en los documentos de la API, ya que hay más parámetros y funciones más útiles (como para las monedas:) format_currency.
Daniel W.
3

Oh, esa es una bestia interesante.

He dedicado un tiempo considerable a hacerlo bien, hay tres problemas principales que difieren de un lugar a otro: - símbolo de moneda y dirección - separador de miles - punto decimal

He escrito mi propia implementación bastante extensa de esto, que es parte del marco de kiwi python, consulte la fuente LGPL: ed aquí:

http://svn.async.com.br/cgi-bin/viewvc.cgi/kiwi/trunk/kiwi/currency.py?view=markup

El código es ligeramente específico de Linux / Glibc, pero no debería ser demasiado difícil de adoptar en Windows u otros Unix.

Una vez que tenga eso instalado, puede hacer lo siguiente:

>>> from kiwi.datatypes import currency
>>> v = currency('10.5').format()

Que luego te dará:

'$10.50'

o

'10,50 kr'

Dependiendo de la configuración regional seleccionada actualmente.

El punto principal que esta publicación tiene sobre la otra es que funcionará con versiones anteriores de python. locale.currency se introdujo en python 2.5.

Johan Dahlin
fuente
¿Tiene ventajas sobre locale.currency ()?
Ali Afshar
@AliAfshar: Una ventaja sería en 10,50 krlugar de kr 10,50.
user2394284
2

#impresión de la variable 'Total:' en un formato similar a este '9,348.237'

print ('Total:',   '{:7,.3f}'.format(zum1))

donde '{: 7, .3f}' es el número de espacios para formatear el número en este caso es un millón con 3 puntos decimales. Luego agrega el '.format (zum1). El zum1 es la variable que tiene el número grande para la suma de todos los números en mi programa particular. La variable puede ser cualquier cosa que decidas usar.

Marie
fuente
1

Inspirado en el código anterior: D

def money_format(value):
value = str(value).split('.')
money = ''
count = 1

for digit in value[0][::-1]:
    if count != 3:
        money += digit
        count += 1
    else:
        money += f'{digit},'
        count = 1

if len(value) == 1:
    money = ('$' + money[::-1]).replace('$-','-$')
else:
    money = ('$' + money[::-1] + '.' + value[1]).replace('$-','-$')

return money
Elmer González
fuente
0

He llegado a mirar lo mismo y descubrí que Python-money no lo usó realmente todavía, pero tal vez una combinación de los dos sería buena

James Brooks
fuente
0

Una lambda para calcularlo dentro de una función, con la ayuda de la respuesta de @ Nate

converter = lambda amount, currency: "%s%s%s" %(
    "-" if amount < 0 else "", 
    currency, 
    ('{:%d,.2f}'%(len(str(amount))+3)).format(abs(amount)).lstrip())

y entonces,

>>> converter(123132132.13, "$")
'$123,132,132.13'

>>> converter(-123132132.13, "$")
'-$123,132,132.13'
mu 無
fuente
La mayoría de los países usan el símbolo de la moneda después de la cantidad, no al revés.
Jonas Byström
@jonas Tal vez eso es lo que la mayoría de los países lo hacen, pero OP tenido antes la cantidad, por lo tanto, lo tengo antes de que el importe en mi respuesta también :)
mu無
0

Código simple de python!

def format_us_currency(value):
    value=str(value)
    if value.count(',')==0:
        b,n,v='',1,value
        value=value[:value.rfind('.')]
        for i in value[::-1]:
            b=','+i+b if n==3 else i+b
            n=1 if n==3 else n+1
        b=b[1:] if b[0]==',' else b
        value=b+v[v.rfind('.'):]
    return '$'+(value.rstrip('0').rstrip('.') if '.' in value else value)
Vanjith
fuente
1
Sus cadenas devuelve un código como "$2,129.1468284147656", "$10,948.3742933", "$1,0908". Garbles la cuerda.
Eugene Gr. Philippov
Sí, no me di cuenta. También has dado los ans.
Vanjith