Pytanie Jak parsować ciąg do float lub int w Pythonie?


W Pythonie, jak mogę parsować łańcuch liczbowy jak "545.2222" do odpowiadającej mu wartości zmiennoprzecinkowej, 542.2222? Lub przeanalizuj ciąg znaków "31" do liczby całkowitej, 31?

Chcę tylko wiedzieć, jak parsować pływak  string do a floati (oddzielnie) int  string do int.


1761
2017-12-19 01:52


pochodzenie


Zasadniczo, jeśli masz obiekt w Pythonie i chcesz go przekonwertować do ten typ obiektu, zadzwoń type(my_object) na tym. Wynik można zwykle wywoływać jako funkcję konwersji. Na przykład type(100) prowadzi do int, więc możesz zadzwonić int(my_object) spróbować przekonwertować my_object do liczby całkowitej. To nie zawsze działa, ale jest dobrym "pierwszym domysłem" podczas kodowania. - robertlayton


Odpowiedzi:


>>> a = "545.2222"
>>> float(a)
545.22220000000004
>>> int(float(a))
545

2087
2017-12-19 01:54



tylko zastanawiasz się, dlaczego w końcu jest "04"? dlaczego nie po prostu "00"? również moja obecna wersja Pythona nie ma "04". - Mangat Rai Modi
@MangatRaiModi Liczby zmiennoprzecinkowe są z natury niedoskonałe do reprezentowania wartości dziesiętnych. Aby uzyskać więcej informacji, zobacz stackoverflow.com/q/21895756/931277 - dokkaebi
dlaczego nie po prostu int(a) ale int(float(a)) ? - user463035818
int(a) spowoduje błąd, że ciąg nie jest prawidłową liczbą całkowitą: ValueError: invalid literal for int() with base 10: '545.222', ale konwersja z float na int jest obsługiwaną konwersją. - David Parks


def num(s):
    try:
        return int(s)
    except ValueError:
        return float(s)

443
2017-12-19 02:31



domniemany mieszanie floats / int może prowadzić do subtelnych błędów z powodu możliwej utraty precyzji podczas pracy z float lub dla różnych wyników / operator na floats / ints. W zależności od kontekstu może być lepiej powrócić do zmiennej int lub float, a nie do obu. - jfs
@ J.F.Sebastian Jesteś całkowicie poprawny, ale są chwile, kiedy chcesz, aby dane wejściowe dyktowały, który z nich będzie. Pozwalanie na wprowadzanie dyktować, które można ładnie pracować z kaczym typowaniem. - TimothyAWiseman
Możesz zagnieździć innego try rzucać wyjątek, gdy nie można go zamienić na wartość zmiennoprzecinkową. - iBug


Metoda Pythona do sprawdzania, czy łańcuch jest zmiennoprzecinkowy:

def isfloat(value):
  try:
    float(value)
    return True
  except:
    return False

Dłuższą i dokładniejszą nazwą tej funkcji może być: isConvertibleToFloat(value)

Co to jest i nie jest zmienne Pyton może cię zaskoczyć:

val                   isfloat(val) Note
--------------------  ----------   --------------------------------
""                    False        Blank string
"127"                 True         Passed string
True                  True         Pure sweet Truth
"True"                False        Vile contemptible lie
False                 True         So false it becomes true
"123.456"             True         Decimal
"      -127    "      True         Spaces trimmed
"\t\n12\r\n"          True         whitespace ignored
"NaN"                 True         Not a number
"NaNanananaBATMAN"    False        I am Batman
"-iNF"                True         Negative infinity
"123.E4"              True         Exponential notation
".1"                  True         mantissa only
"1,234"               False        Commas gtfo
u'\x30'               True         Unicode is fine.
"NULL"                False        Null is not special
0x3fade               True         Hexadecimal
"6e7777777777777"     True         Shrunk to infinity
"1.797693e+308"       True         This is max value
"infinity"            True         Same as inf
"infinityandBEYOND"   False        Extra characters wreck it
"12.34.56"            False        Only one dot allowed
u'四'                 False        Japanese '4' is not a float.
"#56"                 False        Pound sign
"56%"                 False        Percent of what?
"0E0"                 True         Exponential, move dot 0 places
0**0                  True         0___0  Exponentiation
"-5e-5"               True         Raise to a negative number
"+1e1"                True         Plus is OK with exponent
"+1e1^5"              False        Fancy exponent not interpreted
"+1e1.3"              False        No decimals in exponent
"-+1"                 False        Make up your mind
"(1)"                 False        Parenthesis is bad

Myślisz, że wiesz, jakie są liczby? Nie jesteś taki dobry, jak myślisz! Niezbyt zaskakujące.


416
2018-01-05 04:15



Rozważ zmianę nazwy funkcji na convertibleToFloat lub coś podobnego (obecna nazwa wydaje się być myląca, przynajmniej dla mnie). - MKPS


Jest to kolejna metoda, o której warto tutaj wspomnieć, ast.literal_eval:

Może to służyć do bezpiecznego oceniania ciągów zawierających wyrażenia Python z niezaufanych źródeł bez potrzeby analizowania wartości.

Oznacza to, że bezpieczny "eval"

>>> import ast
>>> ast.literal_eval("545.2222")
545.2222
>>> ast.literal_eval("31")
31

104
2018-03-01 04:23



to jest nie dobre rozwiązanie problemu. Działa dobrze w Pythonie 2, ale w Pythonie 3 następują: python >>> import ast >>> ast.literal_eval('1-800-555-1212') -2566 >>>   Aby wyjaśnić, dlaczego jest to problem, jeśli chcesz zostawić numery telefonów w spokoju i nie zakładać, że są to wyrażenia matematyczne, to takie podejście nie jest dla Ciebie. - royce3
@ Royce3 Tak, to dobra uwaga, a użytkownicy powinni się wystrzegać. Zachowanie zostało pierwotnie zmodyfikowane w celu rozwiązania niektórych problemów z analizą złożonych literałów. To prawdopodobnie błąd w ast.literal_evali zostało omówione tutaj. - wim


float(x) if '.' in x else int(x)

74
2017-12-19 02:32



Nitpick: nie działa w ekstremalnych przypadkach, takich jak float ("2e-3") - Emile
Uwaga: należy zachować ostrożność w przypadku kwot pieniężnych przekazywanych jako łańcuchy znaków, ponieważ niektóre kraje używają "," jako separatorów dziesiętnych - Ben G
@Emile: Nie nazwałbym "2e-3" "przypadkiem ekstremalnym". Ta odpowiedź jest po prostu zepsuta. - jchl
@ BENG NIE manipuluj pieniędzmi jako float. To powoduje kłopoty. Użyj wartości dziesiętnej dla pieniędzy! (Ale twój komentarz na temat "," jest nadal ważny i ważny) - ToolmakerSteve
Nie zapominaj, że "nie liczba" (NaN) i +/- nieskończoność są również ważnymi wartościami zmiennoprzecinkowymi. Więc float("nan") jest całkowicie poprawną wartością zmienną, której powyższa odpowiedź w ogóle by nie złapała - Ronny Andersson


Lokalizacja i przecinki

Powinieneś rozważyć możliwość przecinków w łańcuchowej reprezentacji liczby, dla przypadków takich jak float("545,545.2222") który zgłasza wyjątek. Zamiast tego użyj metod w locale konwertować łańcuchy na liczby i poprawnie interpretować przecinki. The locale.atof metoda konwertuje na zmienną w jednym kroku po ustawieniu ustawień narodowych dla żądanej konwencji liczbowej.

Przykład 1 - Konwencje o numerach w Stanach Zjednoczonych 

W Stanach Zjednoczonych i Wielkiej Brytanii przecinki mogą być używane jako separator tysięcy. W tym przykładzie z amerykańskim ustawieniem regionalnym przecinek jest traktowany poprawnie jako separator:

>>> import locale
>>> a = u'545,545.2222'
>>> locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
'en_US.UTF-8'
>>> locale.atof(a)
545545.2222
>>> int(locale.atof(a))
545545
>>>

Przykład 2 - Europejskie konwencje dotyczące numerów

w większość krajów świataprzecinki są używane dla znaków dziesiętnych zamiast kropek. W tym przykładzie z francuskim ustawieniem regionalnym przecinek jest poprawnie traktowany jako znak dziesiętny:

>>> import locale
>>> b = u'545,2222'
>>> locale.setlocale(locale.LC_ALL, 'fr_FR')
'fr_FR'
>>> locale.atof(b)
545.2222

Metoda locale.atoi jest również dostępny, ale argument powinien być liczbą całkowitą.


45
2017-07-23 16:00





Użytkownicy codelogiczny i harley są poprawne, ale pamiętaj, jeśli wiesz, że ciąg jest liczbą całkowitą (na przykład 545), możesz wywołać int ("545") bez wcześniejszego rzucania do float.

Jeśli twoje struny są na liście, możesz również użyć funkcji mapy.

>>> x = ["545.0", "545.6", "999.2"]
>>> map(float, x)
[545.0, 545.60000000000002, 999.20000000000005]
>>>

Jest to dobre tylko wtedy, gdy wszystkie są tego samego typu.


22
2017-12-19 02:09





Jeśli nie masz nic przeciwko modułom stron trzecich, możesz sprawdzić fastnumbers moduł. Zapewnia funkcję o nazwie fast_real dokładnie to, o co pyta to pytanie, i robi to szybciej niż implementacja czysto-Pythona:

>>> from fastnumbers import fast_real
>>> fast_real("545.2222")
545.2222
>>> type(fast_real("545.2222"))
float
>>> fast_real("31")
31
>>> type(fast_real("31"))
int

21
2017-08-14 03:21





W Pythonie, jak mogę sparsować ciąg numeryczny, taki jak "545.2222", do odpowiadającej mu wartości float, 542.2222? Lub sparsuj ciąg "31" do liczby całkowitej, 31?   Chcę tylko wiedzieć, jak parsować ciąg float do float i (oddzielnie) int string do int.

Dobrze, że prosisz o to osobno. Jeśli je miksujesz, możesz później ustawić się na problemy. Prosta odpowiedź brzmi:

"545.2222" unosić:

>>> float("545.2222")
545.2222

"31"do liczby całkowitej:

>>> int("31")
31

Inne konwersje, od do i od ciągów i literałów:

Konwersje z różnych baz i powinieneś znać bazę z góry (domyślnie 10). Zauważ, że możesz poprzedzić je tym, czego Python oczekuje od swoich literałów (patrz poniżej) lub usunąć prefiks:

>>> int("0b11111", 2)
31
>>> int("11111", 2)
31
>>> int('0o37', 8)
31
>>> int('37', 8)
31
>>> int('0x1f', 16)
31
>>> int('1f', 16)
31

Jeśli nie znasz bazy z góry, ale wiesz, że będą miały poprawny prefiks, Python może to dla ciebie wnioskować, jeśli zdasz 0 jako podstawa:

>>> int("0b11111", 0)
31
>>> int('0o37', 0)
31
>>> int('0x1f', 0)
31

Non-Decimal (czyli Integer) Literały z innych baz

Jeśli twoja motywacja polega na tym, aby twój własny kod wyraźnie reprezentował zakodowane określone wartości, możesz nie potrzebować konwertować z baz - możesz pozwolić, aby Python zrobił to automatycznie za pomocą poprawnej składni.

Możesz użyć przedrostków apropos, aby uzyskać automatyczną konwersję na liczby całkowite za pomocą następujące literały. Te są ważne dla Pythona 2 i 3:

Binarny, prefiks 0b

>>> 0b11111
31

Oktal, prefiks 0o

>>> 0o37
31

Szesnastkowy, prefiks 0x

>>> 0x1f
31

Może to być przydatne przy opisywaniu flag binarnych, uprawnień do plików w kodzie lub wartościach heksadecymalnych dla kolorów - na przykład notatek bez cudzysłowów:

>>> 0b10101 # binary flags
21
>>> 0o755 # read, write, execute perms for owner, read & ex for group & others
493
>>> 0xffffff # the color, white, max values for red, green, and blue
16777215

Sprawianie, aby dwuznaczny Python 2 octals był kompatybilny z Pythonem 3

Jeśli widzisz liczbę całkowitą zaczynającą się od 0, w Pythonie 2 jest to (przestarzała) składnia ósemkowa.

>>> 037
31

Jest źle, ponieważ wygląda na to, że wartość powinna być 37. Tak więc w Pythonie 3, teraz podnosi a SyntaxError:

>>> 037
  File "<stdin>", line 1
    037
      ^
SyntaxError: invalid token

Konwertuj 2 oktale w Pythonie na ósemki, które działają zarówno w wersjach 2, jak i 3, za pomocą 0o prefiks:

>>> 0o37
31

17
2017-07-23 13:26