W Pythonie, w jaki sposób można analizować ciąg liczbowy jak "545.2222"
do odpowiadającej jej wartości float 545.2222
? Lub parsować ciąg "31"
do liczby całkowitej 31
?
Chcę tylko wiedzieć, jak parsować zmiennoprzecinkowe str
do float
i (osobno) int str
do int
.
python
parsing
floating-point
type-conversion
integer
Tristan Havelick
źródło
źródło
type(my_object)
go. Wynik można zwykle wywołać jako funkcję konwersji. Na przykładtype(100)
powodujeint
, że możesz zadzwonić,int(my_object)
aby spróbować przekonwertowaćmy_object
na liczbę całkowitą. To nie zawsze działa, ale jest dobrym „pierwszym odgadnięciem” podczas kodowania.int(x) if int(x) == float(x) else float(x)
Odpowiedzi:
źródło
int(a)
aleint(float(a))
?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 liczby zmiennoprzecinkowej na liczbę całkowitą jest obsługiwaną konwersją.ValueError
jeśli chcesz być bezpiecznyźródło
/
operatora liczb zmiennoprzecinkowych / liczb całkowitych. W zależności od kontekstu może być wskazane zwrócenie int lub float, a nie obu.try
aby zgłosić wyjątek, gdy nie można go zamienić na zmiennoprzecinkowy.s = u'\u0000'
ValueError
odpowiedniegoexcept
: PMetoda Pythona, aby sprawdzić, czy ciąg jest liczbą zmiennoprzecinkową:
Dłuższą i dokładniejszą nazwą tej funkcji może być:
is_convertible_to_float(value)
Co jest, a nie jest zmiennoprzecinkowe w Pythonie, może cię zaskoczyć:
Myślisz, że wiesz, jakie są liczby? Nie jesteś tak dobry, jak myślisz! Nie wielka niespodzianka.
Nie używaj tego kodu w oprogramowaniu krytycznym dla życia!
Łapanie w ten sposób szerokich wyjątków, zabijanie kanarków i pożeranie wyjątku stwarza niewielką szansę, że prawidłowy zmiennoprzecinkowy ciąg znaków zwróci false.
float(...)
Linia kodu może nie powiodła się dla żadnego z tysiąca powodów, które nie mają nic wspólnego z treścią napisu. Ale jeśli piszesz krytyczne oprogramowanie w kaczym prototypowym języku, takim jak Python, masz znacznie większe problemy.źródło
UTF-8
glif dla Chińczyków4
zmieniał się przez lata, w zależności od tego, jak programiści Stackoverflow zmieniają schemat kodowania znaków po zastosowaniu pakietu narzędzi Microsoft. Z ciekawością patrzy się, jak zmienia się z biegiem lat, gdy nowe schematy konwersji potwierdzają swoje nowe ideologie. Ale tak, każdyUTF-8
glif dla wschodnich liczb orientalnych nie jest pływakiem Pythona. Bazinga."- 12.3"
i"45 e6"
TypeError, ValueError
Jest to kolejna metoda, o której warto wspomnieć tutaj, ast.literal_eval :
To znaczy, bezpieczna „ewaluacja”
źródło
python >>> import ast >>> ast.literal_eval('1-800-555-1212') -2566 >>>
Aby wyjaśnić, dlaczego jest to problem, jeśli chcesz, aby pozostawiał numery telefonów w spokoju i nie zakładał, że są wyrażeniami matematycznymi, to podejście nie jest dla Ciebie.ast.literal_eval
, który został tutaj omówiony .źródło
float("nan")
Jest to więc całkowicie poprawna wartość zmiennoprzecinkowa, której powyższa odpowiedź w ogóle nie złapie192.168.0.1
; lub"This is not a good approach. :)"
Lokalizacja i przecinki
Należy wziąć pod uwagę możliwość przecinków w reprezentacji ciągu liczby, w przypadkach takich jak
float("545,545.2222")
który zgłasza wyjątek. Zamiast tego użyj metod w,locale
aby przekonwertować ciągi na liczby i poprawnie interpretować przecinki. Telocale.atof
metody przekształca się w obrocie w jednym etapie raz na lokalizacji jest ustawiony w pożądanym Konwencji numerycznej.Przykład 1 - Konwencje liczbowe w Stanach Zjednoczonych
W Stanach Zjednoczonych i Wielkiej Brytanii przecinki mogą być używane jako separator tysięcy. W tym przykładzie z amerykańskimi ustawieniami narodowymi przecinek jest poprawnie traktowany jako separator:
Przykład 2 - Europejskie konwencje liczbowe
W większości krajów świata przecinki są używane jako znaki dziesiętne zamiast kropek. W tym przykładzie z ustawieniami francuskimi przecinek jest poprawnie obsługiwany jako znak dziesiętny:
Metoda
locale.atoi
jest również dostępna, ale argumentem powinna być liczba całkowita.źródło
x = '1'; locale.atof(x)
zwraca,1.0
gdy naprawdę chcę1
.locale.atof(x) if locale.localeconv().get('decimal_point') in x else locale.atoi(x)
locale.atoi
locale.atof
Jeśli nie jesteś przeciwny modułom innych firm, możesz sprawdzić moduł fastnumbers . Zapewnia funkcję o nazwie fast_real, która robi dokładnie to, o co pyta to pytanie i działa szybciej niż implementacja czysto Python:
źródło
Użytkownicy codelogic i harley są poprawni, ale pamiętaj, jeśli wiesz, że ciąg jest liczbą całkowitą (na przykład 545), możesz wywołać int („545”) bez pierwszego rzutowania na zmiennoprzecinkowe.
Jeśli twoje ciągi znajdują się na liście, możesz również użyć funkcji mapy.
Dobrze jest, jeśli wszystkie są tego samego typu.
źródło
Dobrze, że poprosisz o zrobienie tego osobno. Jeśli je miksujesz, być może będziesz się później przygotowywał na problemy. Prosta odpowiedź brzmi:
"545.2222"
unosić:"31"
do liczby całkowitej:Inne konwersje, ints do iz ciągów znaków i literałów:
Konwersje z różnych baz i powinieneś znać bazę z góry (domyślnie jest to 10). Pamiętaj, że możesz poprzedzić je tym, czego oczekuje Python od jego literałów (patrz poniżej) lub usunąć prefiks:
Jeśli nie znasz bazy z góry, ale wiesz, że będą miały poprawny przedrostek, Python może wywnioskować to, jeśli podasz
0
jako podstawę:Literały nie dziesiętne (tj. Całkowite) z innych baz
Jeśli twoją motywacją jest posiadanie własnego kodu wyraźnie reprezentującego określone, zakodowane na stałe wartości, może nie być konieczne konwertowanie z baz - możesz pozwolić Pythonowi zrobić to automatycznie za pomocą właściwej składni.
Możesz użyć przedrostków apropos, aby uzyskać automatyczną konwersję na liczby całkowite o następujących literałach . Są one ważne dla Pythona 2 i 3:
Binarny, prefiks
0b
Oktalowy, przedrostek
0o
Szesnastkowy, przedrostek
0x
Może to być przydatne przy opisywaniu flag binarnych, uprawnień do plików w kodzie lub wartości szesnastkowych dla kolorów - na przykład nie zauważaj cudzysłowów:
Dostosowywanie dwuznacznych oktałów Python 2 do Python 3
Jeśli widzisz liczbę całkowitą rozpoczynającą się od 0, w Pythonie 2 jest to (przestarzała) składnia ósemkowa.
Jest źle, ponieważ wygląda na to, że wartość powinna być
37
. W Pythonie 3 pojawia się terazSyntaxError
:Konwertuj liczby ósemkowe w języku Python 2 na liczby ósemkowe, które działają zarówno w 2, jak i 3 z
0o
prefiksem:źródło
Pytanie wydaje się trochę stare. Ale pozwól, że zasugeruję funkcję, parseStr, która czyni coś podobnego, to znaczy zwraca liczbę całkowitą lub zmiennoprzecinkową, a jeśli dany ciąg ASCII nie może zostać przekonwertowany na żadną z nich, zwraca go nietknięty. Kod można oczywiście dostosować tak, aby robił tylko to, co chcesz:
źródło
1e3
to liczba w pythonie, ale ciąg zgodny z twoim kodem.float("545.2222")
iint(float("545.2222"))
źródło
Używam do tego tej funkcji
Przekształci ciąg na swój typ
źródło
parse_str(' 1')
(ze spacją) wróciNone
, nie1
.YAML parser może pomóc dowiedzieć się, co typ danych ciąg jest. Użyj
yaml.load()
, a następnie możesz użyćtype(result)
do przetestowania typu:źródło
źródło
except
sekcji, jeśli nic tam nie robisz? float () podbije za ciebie.int
albo wfloat
zależności od tego, co reprezentuje ciąg. Może pojawić się parsowanie wyjątków lub [mieć nieoczekiwane zachowanie] [1].źródło
Aby to zrobić poprawnie, należy wziąć pod uwagę zaokrąglenie.
Tj. Int (5.1) => 5 int (5.6) => 5 - źle, powinno być 6, więc robimy int (5.6 + 0.5) => 6
źródło
int
ifloat
. I da wyjątek, gdyn
jest łańcuchem, zgodnie z życzeniem OP. Może masz na myśli: Kiedyint
jest pożądany wynik,round
należy zrobić konwersji PO unosić. Jeśli funkcja powinna ZAWSZE zwracać liczbę całkowitą, to nie potrzebujesz części wyjątkowej - cała treść funkcji może byćint(round(float(input)))
. Jeśli funkcja zwraca int, jeśli to możliwe, w przeciwnym razie zmiennoprzecinkowe, oryginalne rozwiązanie javier jest poprawne!Dziwi mnie, że nikt nie wspominał o wyrażeniu regularnym, ponieważ czasami ciąg musi być przygotowany i znormalizowany przed rzutem na liczbę
stosowanie:
a przy okazji, coś do zweryfikowania masz numer:
źródło
Aby typecast w Pythonie, użyj funkcji konstruktora typu, przekazując ciąg (lub dowolną wartość, którą próbujesz rzutować) jako parametr.
Na przykład:
Za kulisami Python wywołuje
__float__
metodę object, która powinna zwrócić zmienną reprezentację parametru. Jest to szczególnie wydajne, ponieważ można definiować własne typy (za pomocą klas) za pomocą__float__
metody, dzięki czemu można go rzutować na zmiennoprzecinkowe za pomocą zmiennoprzecinkowego (myobject).źródło
Jest to poprawiona wersja z https://stackoverflow.com/a/33017514/5973334
Spróbuje to parsować ciąg i zwróci albo albo,
int
albo wfloat
zależności od tego, co reprezentuje ciąg. Może to powodować wyjątki parsowania lub mieć nieoczekiwane zachowanie .źródło
Przekaż ciąg znaków do tej funkcji:
Zwróci int, float lub string w zależności od tego, co zostało przekazane.
ciąg znaków, który jest liczbą całkowitą
ciąg znaków, który jest liczbą zmiennoprzecinkową
ciąg, który jest ciągiem
ciąg, który wygląda jak pływak
źródło
Posługiwać się:
To najbardziej pythoniczny sposób, jaki mogłem wymyślić.
źródło
float
.try
...catch
blok powinien prawdopodobnie wewnątrzfor
pętli.Obsługuje wartości szesnastkowe, ósemkowe, binarne, dziesiętne i zmiennoprzecinkowe
To rozwiązanie poradzi sobie ze wszystkimi konwencjami ciągów liczb (wszystko, o czym wiem).
Dane wyjściowe przypadku testowego ilustrują to, o czym mówię.
Oto test:
źródło
Posługiwać się:
źródło
Jest to funkcja, która konwertuje dowolny
object
(nie tylkostr
) naint
lubfloat
, w zależności od tego, czy podany ciąg znaków wygląda jakint
lubfloat
. Ponadto, jeśli jest to obiekt posiadający obie metody__float
i__int__
metody, domyślnie używa__float__
źródło
Za pomocą metod int i float możemy przekonwertować ciąg znaków na liczbę całkowitą i liczby zmiennoprzecinkowe.
źródło
eval()
jest bardzo dobrym rozwiązaniem tego pytania. Nie musi sprawdzać, czy liczba jest liczbą całkowitą czy zmienną, po prostu daje odpowiedni ekwiwalent. Jeśli wymagane są inne metody, spróbujtry-wyjątkiem może być również użyty jako alternatywa. Spróbuj przekonwertować ciąg znaków na int w bloku try. Jeśli ciąg będzie wartością zmiennoprzecinkową, wygeneruje błąd, który zostanie wyłapany w bloku wyjątkiem, tak jak to
źródło
Oto kolejna interpretacja twojego pytania (wskazówka: jest niejasna). Możliwe, że szukasz czegoś takiego:
Działa to tak ...
Teoretycznie istnieje usterka polegająca na wstrzyknięciu. Łańcuch może na przykład być
"import os; os.abort()"
. Jednak bez żadnego tła, skąd pochodzi ta struna, istnieje możliwość teoretycznych spekulacji. Ponieważ pytanie jest niejasne, wcale nie jest jasne, czy ta luka rzeczywiście istnieje, czy nie.źródło
eval()
jest ponad 3 razy wolniejszy niżtry: int(s) except: float(s)
.eval
to zła praktyka (musisz wiedzieć, ponieważ masz 310 tys. Reputacji)