Formatage des devises en Python


156

Je cherche à formater un nombre comme 188518982.18 à 188 518 982,18 £ en utilisant Python.

Comment puis-je faire ceci?


Vous avez fait un excellent point dans un commentaire ci-dessous, @RailsSon: vous voulez imprimer des £ pour afficher une devise spécifique, mais utilisez cet affichage en utilisant une expression japonaise pour les chiffres financiers. Je trouve étrange que votre demande n'ait pas été implémentée dans la langue en découplant l' localeutilisation de la valeur de la devise par le module et les propriétés d'affichage de cette devise.
Droogans

Réponses:


212

Voir le module de paramètres régionaux .

Cela fait le formatage de la devise (et de la date).

>>> 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'

15
Comment formater correctement une devise non native, disons que j'affiche un coût en livres sterling pour un rapport en japonais?
SingleNegationElimination

2
@TokenMacGuy: C'est une question piège. Le rapport japonais signifie les règles japonaises de virgule et de décimale, mais le symbole de devise GB Pound - pas trivialement pris en charge par Locale. Vous devez créer une définition de paramètres régionaux personnalisée.
S.Lott le

si le nombre de donneur est négatif renvoie la valeur entre "()" pourquoi?
panchicore

6
Cela ne fonctionnait toujours pas pour moi, mais je l'ai changé locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')et cela a parfaitement fonctionné!
Furbeenator

2
@panchicore la notation des nombres négatifs comme indiqué par des parenthèses est une pratique courante dans le monde de la comptabilité. Essayez-le dans oocalc ou excel et formatez les nombres selon le type de comptabilité.
Droogans du

94

Nouveau dans 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


6
C'est bien mais ne répond pas vraiment à la question, car la solution demandée comprendrait un symbole monétaire, et vous codez également en dur le nombre de chiffres après la décimale, qui est spécifique à la langue. Il existe de nombreuses autres raisons d'utiliser la réponse locale acceptée si vous ne voulez pas simplement placer une virgule.
mrooney

6
@mrooney Il existe également de nombreuses raisons de ne pas utiliser la réponse locale acceptée, comme par exemple ne pas importer un module entier.
Josh

1
@Josh, "à partir de la devise d'importation locale".
Andrew H du

5
@mrooney: Vous pouvez simplement faire: '$ {: 0, .2f}'. format (184467616.1), et vous avez maintenant le symbole
triunenature

@triunenature qui en résulterait $ 123,456.78parfois cependant. Edit: le démarque supprime les espaces supplémentaires, prétendez qu'il y a plus entre le $ et les nombres
CyberJacob

48

Je ne sais pas trop pourquoi cela n'est pas mentionné plus en ligne (ou sur ce fil), mais le package Babel (et les utilitaires Django) des gars d'Edgewall est génial pour le formatage des devises (et beaucoup d'autres tâches i18n). C'est bien car il ne souffre pas de la nécessité de tout faire globalement, comme le module principal de paramètres régionaux Python.

L'exemple donné par l'OP serait simplement:

>>> import babel.numbers
>>> import decimal
>>> babel.numbers.format_currency( decimal.Decimal( "188518982.18" ), "GBP" )
£188,518,982.18

2
Note très tardive: en testant cela, il ne semble pas formater intelligemment la devise, car il colle simplement le symbole approprié avant le montant (formaté dans ce qui semble être le paramètre régional que vous avez défini, ce qui est raisonnable), que cette devise soit réellement utilise son symbole comme préfixe.
kungphu

@kungphu Que voulez-vous dire? Voir babel.pocoo.org/en/latest/api
Julian

1
@Julian Il semble que l' localeargument to format_currencypuisse être utilisé pour résoudre ce problème, mais soit ce n'était pas dans la doc il y a quatre ans (quand j'ai écrit ce commentaire) ou j'ai juste testé le code de cette réponse tel quel sans vérifier la doc.
kungphu

1
@kungphu Gotcha. Je n'ai pas dû faire attention à l'âge de ce poste hier. Le changement de documentation / fonction semble très probable. À votre santé!
Julian

32

Ceci est un article ancien, mais je viens de mettre en œuvre la solution suivante qui:

  • Ne nécessite pas de modules externes
  • Ne nécessite pas la création d'une nouvelle fonction
  • Peut être fait en ligne
  • Gère plusieurs variables
  • Gère les montants négatifs en dollars

Code:

num1 = 4153.53
num2 = -23159.398598

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

Production:

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

Et pour l'affiche originale, évidemment, il suffit de changer $pour£


mon format nécessitait une certaine personnalisation, mais ce n'est pas grave car j'ai pu le faire avec cette solution.
DonkeyKong

10
Bonne idée! Avec Python 3.6 et f-strings, c'est encore plus beau:print(f'Value is: ${value:,.2f}'.replace('$-', '-$'))
Timo Saloranta

16

Mes paramètres régionaux semblaient incomplets, donc j'avais trop regardé au-delà de cette réponse SO et trouvé:

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

Indépendant du système d'exploitation

Je voulais juste partager ici.


Mais où appelons-nous le def moneyfmt(value, places=2, curr='', sep=',', dp='.', pos='', neg='-', trailneg='')?
Roel

9

Si vous utilisez OSX et que vous n'avez pas encore défini le paramètre de votre module de paramètres régionaux, cette première réponse ne fonctionnera pas, vous recevrez l'erreur suivante:

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.

Pour remédier à cela, vous devrez utiliser les éléments suivants:

locale.setlocale(locale.LC_ALL, 'en_US')

2
locale.setlocale (locale.LC_ALL, 'en_US.UTF-8') fait pour moi
alexblum

9

"{:0,.2f}".format(float(your_numeric_value))dans Python 3 fait le travail; il donne quelque chose comme l'une des lignes suivantes:

10,938.29
10,899.00
10,898.99
2,328.99

6

Si j'étais vous, j'utiliserais BABEL: http://babel.pocoo.org/en/latest/index.html

from babel.numbers import format_decimal


format_decimal(188518982.18, locale='en_US')

1
Le module de localisation python ne fonctionnait pas pour moi (quelle que soit la locale que je l'ai définie, il se plaignait) mais exiger babel et utiliser cette fonction est bien. Cela vaut la peine de jeter un œil dans la documentation de l'API car il y a plus de paramètres et de fonctions plus utiles (comme pour les devises :) format_currency.
Daniel W.

3

Oh, c'est une bête intéressante.

J'ai passé beaucoup de temps à y parvenir, il y a trois problèmes principaux qui diffèrent d'une locale à l'autre: - symbole et direction de la devise - séparateur des milliers - point décimal

J'ai écrit ma propre implémentation assez étendue de ceci qui fait partie du framework kiwi python, consultez la source LGPL: ed ici:

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

Le code est légèrement spécifique à Linux / Glibc, mais ne devrait pas être trop difficile à adopter pour Windows ou d'autres Unix.

Une fois que vous l'avez installé, vous pouvez effectuer les opérations suivantes:

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

Ce qui vous donnera alors:

'$10.50'

ou

'10,50 kr'

Selon les paramètres régionaux actuellement sélectionnés.

Le point principal de cet article par rapport à l'autre est qu'il fonctionnera avec les anciennes versions de python. locale.currency a été introduit dans python 2.5.


At-il des avantages par rapport à locale.currency ()?
Ali Afshar

@AliAfshar: Un avantage serait 10,50 krau lieu de kr 10,50.
user2394284

2

#impression de la variable 'Total:' dans un format qui ressemble à ceci '9,348.237'

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

où '{: 7, .3f}' est le nombre d'espaces pour formater le nombre dans ce cas est un million avec 3 décimales. Ensuite, vous ajoutez le '.format (zum1). Le zum1 est la variable qui a le grand nombre pour la somme de tous les nombres dans mon programme particulier. La variable peut être tout ce que vous décidez d'utiliser.


1

Inspiré du code ci-dessus: 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

0

J'en suis venu à regarder la même chose et j'ai trouvé que l' argent python ne l'utilisait pas encore vraiment, mais peut-être qu'un mélange des deux serait bien


0

Un lambda pour le calculer dans une fonction, avec l'aide de la réponse de @ Nate

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

puis,

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

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

La plupart des pays utilisent le symbole monétaire après le montant, et non l'inverse.
Jonas Byström

@jonas C'est peut-être ce que font la plupart des pays, mais OP l'avait avant le montant, donc je l'ai aussi avant le montant dans ma réponse :)
mu 無

0

Code python simple!

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)

1
Vos retours de code chaînes comme "$2,129.1468284147656", "$10,948.3742933", "$1,0908". Déforme la corde.
Eugene Gr. Philippov

Oui, je n'ai pas remarqué. Vous avez également donné les ans.
Vanjith
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.