J'ai quelques chaînes représentant des nombres avec un format de devise spécifique, par exemple :
money="$6,150,593.22"
Je veux convertir cette chaîne en un nombre
6150593.22
Quelle est la meilleure façon d'y parvenir ?
J'ai quelques chaînes représentant des nombres avec un format de devise spécifique, par exemple :
money="$6,150,593.22"
Je veux convertir cette chaîne en un nombre
6150593.22
Quelle est la meilleure façon d'y parvenir ?
Essayez ça :
from re import sub
from decimal import Decimal
money = '$6,150,593.22'
value = Decimal(sub(r'[^\d.]', '', money))
Cette méthode présente certains avantages puisqu'elle utilise Decimal
au lieu de float
(qui est plus adapté à la représentation des devises) et évite également les problèmes de paramètres locaux en ne codant pas en dur un symbole monétaire spécifique.
Si vos paramètres locaux sont correctement définis, vous pouvez utiliser locale.atof
mais vous devrez toujours enlever le "$" manuellement :
>>> import locale
>>> locale.setlocale(locale.LC_ALL, 'en_US.UTF8')
'en_US.UTF8'
>>> money = "$6,150,593.22"
>>> locale.atof(money.strip("$"))
6150593.2199999997
J'ai trouvé le babel
paquet très utile pour travailler autour
Il facilite l'analyse d'un nombre dans un rendu localisé :
>>> babel.numbers.parse_decimal('1,024.64', locale='en')
Decimal('1024.64')
>>> babel.numbers.parse_decimal('1.024,64', locale='de')
Decimal('1024.64')
>>>
Vous pouvez utiliser babel.numbers.get_currency_symbol('USD')
pour supprimer les pré/suffixes sans les coder en dur.
Hth, dtk
Élargissement pour inclure les nombres négatifs entre parenthèses :
In [1]: import locale, string
In [2]: from decimal import Decimal
In [3]: n = ['$1,234.56','-$1,234.56','($1,234.56)', '$ -1,234.56']
In [4]: tbl = string.maketrans('(','-')
In [5]: %timeit -n10000 [locale.atof( x.translate(tbl, '$)')) for x in n]
10000 loops, best of 3: 31.9 æs per loop
In [6]: %timeit -n10000 [Decimal( x.translate(tbl, '$,)')) for x in n]
10000 loops, best of 3: 21 æs per loop
In [7]: %timeit -n10000 [float( x.replace('(','-').translate(None, '$,)')) for x in n]
10000 loops, best of 3: 3.49 æs per loop
In [8]: %timeit -n10000 [float( x.translate(tbl, '$,)')) for x in n]
10000 loops, best of 3: 2.19 æs per loop
Notez que les virgules doivent être supprimées de float()/Decimal(). Soit replace() ou translate() avec une table de traduction peut être utilisé pour convertir l'ouverture ( en -, translate est légèrement plus rapide. float() est plus rapide de 10-15x, mais manque de précision et peut présenter des problèmes de localisation. Decimal() a de la précision et est 50% plus rapide que locale.atof(), mais a aussi des problèmes locaux. locale.atof() est la plus lente, mais la plus générale.
Edit : nouveau str.translate
API (caractères mis en correspondance avec None
déplacé de str.translate
à la table de traduction)
In [1]: import locale, string
from decimal import Decimal
locale.setlocale(locale.LC_ALL, '')
n = ['$1,234.56','-$1,234.56','($1,234.56)', '$ -1,234.56']
In [2]: tbl = str.maketrans('(', '-', '$)')
%timeit -n10000 [locale.atof( x.translate(tbl)) for x in n]
18 µs ± 296 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [3]: tbl2 = str.maketrans('(', '-', '$,)')
%timeit -n10000 [Decimal( x.translate(tbl2)) for x in n]
3.77 µs ± 50.8 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [4]: %timeit -n10000 [float( x.translate(tbl2)) for x in n]
3.13 µs ± 66.3 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [5]: tbl3 = str.maketrans('', '', '$,)')
%timeit -n10000 [float( x.replace('(','-').translate(tbl3)) for x in n]
3.51 µs ± 84.8 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.