Wie konvertiere ich eine Zeichenfolge in eine Zahl, wenn sie Kommas als Tausendertrennzeichen enthält?

83

Ich habe eine Zeichenfolge, die eine Zahl darstellt, bei der Tausende durch Kommas getrennt werden. Wie kann ich dies in eine Zahl in Python konvertieren?

>>> int("1,000,000")

Erzeugt a ValueError.

Ich könnte die Kommas durch leere Zeichenfolgen ersetzen, bevor ich versuche, sie zu konvertieren, aber das fühlt sich irgendwie falsch an. Gibt es einen besseren Weg?

dsimard
quelle

Antworten:

98
import locale
locale.setlocale( locale.LC_ALL, 'en_US.UTF-8' ) 
locale.atoi('1,000,000')
# 1000000
locale.atof('1,000,000.53')
# 1000000.53
unutbu
quelle
9
+1, aber bitte fügen Sie die Gebietsschemaeinstellung hinzu (mit einem Standardgebietsschema 'C'würde dies immer noch ein ValueError! Geben .).
Alex Martelli
1
Ich denke, der Guru bedeutet ungefähr so: locale.setlocale (locale.LC_ALL, 'en_US.UTF-8')
mbarkhau
Danke für die Kommentare. Ich habe ein bestimmtes Gebietsschema hinzugefügt.
Unutbu
Sehr schön. Auf diese Weise kann ich mit europäischen Zahlen umgehen, bei denen auch Kommas und Punkte vertauscht werden. Vielen Dank.
Dsimard
5
Ich erhalte einen Gebietsschemafehler:Traceback (most recent call last): File "F:\test\locale_num.py", line 2, in <module> locale.setlocale( locale.LC_ALL, 'en_US.UTF-8' ) File "F:\Python27\lib\locale.py", line 539, in setlocale return _setlocale(category, locale) locale.Error: unsupported locale setting
Tony Veijalainen
39

Es gibt verschiedene Möglichkeiten, Zahlen mit Tausenden von Trennzeichen zu analysieren. Und ich bezweifle, dass der von @unutbu beschriebene Weg in allen Fällen der beste ist. Deshalb liste ich auch andere Wege auf.

  1. Der richtige Ort zum Anrufen setlocale()ist im __main__Modul. Die globale Einstellung wirkt sich auf das gesamte Programm und sogar auf C-Erweiterungen aus (beachten Sie jedoch, dass die Einstellung LC_NUMERIC nicht auf Systemebene festgelegt, sondern von Python emuliert wird). Lesen Sie die Vorbehalte in der Dokumentation und überlegen Sie zweimal, bevor Sie diesen Weg gehen. Es ist wahrscheinlich in einer einzelnen Anwendung in Ordnung, aber verwenden Sie es niemals in Bibliotheken für ein breites Publikum. Wahrscheinlich sollten Sie vermeiden, ein Gebietsschema mit einer bestimmten Zeichensatzcodierung anzufordern, da es auf einigen Systemen möglicherweise nicht verfügbar ist.

  2. Verwenden Sie eine Bibliothek von Drittanbietern für die Internationalisierung. Mit PyICU können Sie beispielsweise jedes verfügbare Gebietsschema verwenden, ohne den gesamten Prozess zu beeinflussen (und sogar Zahlen mit bestimmten Tausendertrennzeichen ohne Verwendung von Gebietsschemas analysieren):

    NumberFormat.createInstance (Gebietsschema ('en_US')). Parse ("1,000,000"). GetLong ()

  3. Schreiben Sie Ihre eigene Analysefunktion, wenn Sie nicht wissen, wie Sie Bibliotheken von Drittanbietern installieren sollen, um dies "richtig" zu tun. Dies kann so einfach sein, als int(data.replace(',', ''))ob keine strikte Validierung erforderlich wäre.

Denis Otkidach
quelle
1
+1 für die Empfehlung des einfachen Weges. Das war alles was ich brauchte, als ich das gleiche Problem hatte.
Michael Kristofik
Bearbeitet, um einen Tippfehler zu beheben ( setlocatesollte sein setlocale). Auch +1.
Mark Dickinson
Schamlose Eigenwerbung, ich habe die dritte Option verwendet. Also, wenn jemand interessiert ist, werfen Sie einen Blick auf diese Frage / Antwort
Januar
13

Ersetzen Sie die Kommas durch leere Zeichenfolgen und verwandeln Sie die resultierende Zeichenfolge in eine intoder eine float.

>>> a = '1,000,000'
>>> int(a.replace(',' , ''))
1000000
>>> float(a.replace(',' , ''))
1000000.0
Cody Piersall
quelle
21
Bitte lesen Sie noch einmal die OP-Frage. Insbesondere dort, wo er sagt: "Ich könnte die Kommas durch leere Zeichenfolgen ersetzen, bevor ich versuche, sie zu konvertieren, aber das fühlt sich irgendwie falsch an. Gibt es einen besseren Weg?"
Joaquin
1
Ich fand diese Antwort nützlich, da ich fast die gleichen Anforderungen wie das OP habe (strs in ints konvertieren), aber ich bin froh, einen einfacheren Weg als die akzeptierte Antwort zu haben.
Cai
4

Das funktioniert:

(Ein schmutziger, aber schneller Weg)

>>> a='-1,234,567,89.0123'
>>> "".join(a.split(","))
'-123456789.0123'
Wizmann
quelle
3

Ich habe einen Gebietsschemafehler von der akzeptierten Antwort erhalten, aber die folgende Änderung funktioniert hier in Finnland (Windows XP):

import locale
locale.setlocale( locale.LC_ALL, 'english_USA' )
print locale.atoi('1,000,000')
# 1000000
print locale.atof('1,000,000.53')
# 1000000.53
Tony Veijalainen
quelle
1

Ich habe es versucht. Es geht etwas über die Frage hinaus: Sie erhalten eine Eingabe. Es wird zuerst in einen String konvertiert (wenn es sich um eine Liste handelt, z. B. aus Beautiful Suppe). dann zu int, dann zu schweben.

Es geht so weit es geht. Im schlimmsten Fall wird alles, was nicht konvertiert wurde, als Zeichenfolge zurückgegeben.

def to_normal(soupCell):
''' converts a html cell from beautiful soup to text, then to int, then to float: as far as it gets.
US thousands separators are taken into account.
needs import locale'''

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

output = unicode(soupCell.findAll(text=True)[0].string)
try: 
    return locale.atoi(output)
except ValueError: 
    try: return locale.atof(output)
    except ValueError:
        return output
Anderas
quelle
0
>>> import locale
>>> locale.setlocale(locale.LC_ALL, "")
'en_US.UTF-8'
>>> print locale.atoi('1,000,000')
1000000
>>> print locale.atof('1,000,000.53')
1000000.53

Dies geschieht unter Linux in den USA.

Suresh
quelle
-1
#python3 tenzin
def changenum(data):
    foo = ""
    for i in list(data):
        if i == ",":
            continue
        else:
            foo += i
    return  float(int(foo))
Tim und Struppi
quelle
2
Eine Erklärung für diesen Code? Eine Schüssel Suppe wird normalerweise mit einem Suppenlöffel serviert
cs95