Wie analysiere ich einen String in einem float oder int?
-
22-08-2019 - |
Frage
In Python, wie kann ich eine Ziffernfolge wie "545.2222"
zu seinem entsprechenden Float-Wert, 545.2222
analysieren? Oder analysieren Sie die Zeichenfolge "31"
auf eine ganze Zahl, 31
?
Ich will nur wissen, wie ein float str
zu einem float
zu analysieren, und (separat) ein int str
zu einem int
.
Lösung
>>> a = "545.2222"
>>> float(a)
545.22220000000004
>>> int(float(a))
545
Andere Tipps
def num(s):
try:
return int(s)
except ValueError:
return float(s)
Python-Methode zu überprüfen, ob eine Zeichenfolge ein Schwimmer ist:
def is_float(value):
try:
float(value)
return True
except:
return False
Eine längere und genauere Bezeichnung für diese Funktion könnte sein: is_convertible_to_float(value)
Was ist, und ist kein Schwimmer in Python Sie überraschen kann:
val is_float(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
Sie denken, Sie wissen, welche Zahlen sind? Sie sind nicht so gut, wie Sie denken! Nicht große Überraschung.
Verwenden Sie diesen Code nicht auf lebenswichtige Software!
Fangen breite Ausnahmen auf diese Weise, Kanarienvögel zu töten und die Ausnahme gobbling schafft eine winzige Chance, dass ein gültiger Schwimmer als Zeichenfolge falsch zurück. Die float(...)
Codezeile kann aus einem von tausend Gründen gescheitert, die nichts mit dem Inhalt der Zeichenfolge zu tun. Aber wenn Sie schreiben lebenskritische Software in einer Ente-Eingabe Prototyp Sprache wie Python, dann haben Sie, viel größere Probleme.
Dies ist eine weitere Methode, die hier erwähnt zu werden verdient, ast.literal_eval :
Dies kann zur sicheren Auswertung von Zeichenketten enthalten Python-Ausdrücke aus nicht vertrauenswürdigen Quellen, ohne dass sich die Werte analysieren, verwendet werden.
Das heißt, ein sicherer 'eval'
>>> import ast
>>> ast.literal_eval("545.2222")
545.2222
>>> ast.literal_eval("31")
31
float(x) if '.' in x else int(x)
Lokalisierung und Komma
Sie sollten die Möglichkeit Kommas in der String-Darstellung einer Zahl, für Fälle wie float("545,545.2222")
betrachten, die eine Ausnahme auslöst. Verwenden Sie stattdessen Methoden in locale
die Strings in Zahlen zu konvertieren und Kommata richtig zu interpretieren. Die locale.atof
Verfahren wandelt in einem Schwimmer in einem Schritt, sobald die locale wurde für die gewünschte Anzahl Konvention festgelegt wurde.
Beispiel 1 - Vereinigte Staaten Zahl Konventionen
In den Vereinigten Staaten und Großbritannien können Kommas als Tausendertrennzeichen verwendet werden. In diesem Beispiel mit amerikanischen locale, wird das Komma richtig als Separator behandelt:
>>> 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
>>>
Beispiel 2 - Europäische Zahl Konventionen
In der Mehrheit der Länder der Welt , werden Kommas für Dezimalpunkte verwenden anstelle von Perioden. In diesem Beispiel mit Französisch locale, wird das Komma korrekt als Dezimalzeichen behandelt:
>>> import locale
>>> b = u'545,2222'
>>> locale.setlocale(locale.LC_ALL, 'fr_FR')
'fr_FR'
>>> locale.atof(b)
545.2222
Das Verfahren locale.atoi
ist ebenfalls verfügbar, aber das Argument sollte eine ganze Zahl sein.
Wenn Sie nicht abgeneigt sind Module von Drittanbietern, könnten Sie die fastnumbers Modul überprüfen. Es bietet eine Funktion namens fast_real das genau das tut, was diese Frage fordern und tut es schneller als eine reine Python-Implementierung:
>>> 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
Benutzer codelogic und harley korrekt sind, aber denken Sie daran, wenn Sie die Zeichenfolge eine ganze Zahl kennen (zum Beispiel 545), können Sie int nennen ( "545" ), ohne zuerst Gießen zu schweben.
Wenn Sie die Saiten in einer Liste sind, können Sie die Map-Funktion auch nutzen.
>>> x = ["545.0", "545.6", "999.2"]
>>> map(float, x)
[545.0, 545.60000000000002, 999.20000000000005]
>>>
Es ist nur gut, wenn sie alle vom gleichen Typ sind.
Die Frage scheint ein wenig alt. Aber lassen Sie mich schlagen eine Funktion, parseStr, die etwas Ähnliches macht, das heißt, gibt integer oder float und wenn eine bestimmte ASCII-String nicht zu keiner von ihnen umgerechnet werden können es gibt sie unberührt. Der Code natürlich angepasst werden könnte nur das zu tun, was Sie wollen:
>>> import string
>>> parseStr = lambda x: x.isalpha() and x or x.isdigit() and \
... int(x) or x.isalnum() and x or \
... len(set(string.punctuation).intersection(x)) == 1 and \
... x.count('.') == 1 and float(x) or x
>>> parseStr('123')
123
>>> parseStr('123.3')
123.3
>>> parseStr('3HC1')
'3HC1'
>>> parseStr('12.e5')
1200000.0
>>> parseStr('12$5')
'12$5'
>>> parseStr('12.2.2')
'12.2.2'
In Python, wie kann ich eine Ziffernfolge wie „545.2222“ zu seinem entsprechenden Gleitkommawert analysieren, 542.2222? Oder analysieren die Zeichenfolge "31" auf eine ganze Zahl, 31? Ich will nur wissen, wie ein Schwimmer-String mit einem Schwimmer zu analysieren, und (separat) einen int String in einen int.
Es ist gut, dass Sie fragen, diese separat zu tun. Wenn Sie sie abmischen, können Sie sich später für Probleme Einstellung betragen. Die einfache Antwort lautet:
"545.2222"
zu schweben:
>>> float("545.2222")
545.2222
"31"
auf eine ganze Zahl:
>>> int("31")
31
Andere Umwandlungen, ints zu und von Streichern und Literale:
Conversions aus verschiedenen Basen, und Sie sollen die Basis im Voraus (10 ist die Standardeinstellung) kennen. Hinweis: Sie können sie mit dem Präfix, was Python erwartet für seine Literale (siehe unten) oder das Präfix entfernen:
>>> int("0b11111", 2)
31
>>> int("11111", 2)
31
>>> int('0o37', 8)
31
>>> int('37', 8)
31
>>> int('0x1f', 16)
31
>>> int('1f', 16)
31
Wenn Sie nicht wissen, die Basis im Voraus, aber Sie wissen, dass sie den richtigen Präfix haben, Python kann dies für Sie schließen, wenn Sie 0
als Basis übergeben:
>>> int("0b11111", 0)
31
>>> int('0o37', 0)
31
>>> int('0x1f', 0)
31
nichtdezimale (d Integer) Literale aus anderen Basen
Wenn Sie Ihre Motivation Ihren eigenen Code ist eindeutig hartcodierte spezifische Werte darstellen haben, jedoch können Sie nicht von den Basen konvertieren müssen -. Sie können Python lassen tut es für Sie automatisch mit der korrekten Syntax
Sie können die apropos Präfixe verwenden, um die automatische Konvertierung auf ganze Zahlen mit folgende Literale . Diese gelten für Python 2 und 3:
Binary, Präfix 0b
>>> 0b11111
31
Octal, Präfix 0o
>>> 0o37
31
Hexadezimal, Präfix 0x
>>> 0x1f
31
Dies kann nützlich sein, wenn Binärflags beschreibt, Dateiberechtigungen in Code oder Hex-Werte für Farben - zum Beispiel, beachten Sie keine Anführungszeichen:
>>> 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
macht mehrdeutig Python 2 octals kompatibel mit Python 3
Wenn Sie sehen, eine ganze Zahl, die mit einer 0 beginnt, in Python 2, das ist (veraltet) Oktal-Syntax.
>>> 037
31
Es ist schlecht, weil es sieht aus wie sollte der Wert 37
werden. So in Python 3, es stellt sich nun eine SyntaxError
:
>>> 037
File "<stdin>", line 1
037
^
SyntaxError: invalid token
Konvertieren Sie Ihre Python 2 octals zu octals, die sowohl in der 2 und 3 mit dem 0o
Präfix arbeiten:
>>> 0o37
31
float("545.2222")
und int(float("545.2222"))
Die YAML Parser können Ihnen helfen, herauszufinden, was Ihr Datentyp String ist. Verwenden Sie yaml.load()
, und dann können Sie verwenden type(result)
für Typ zu testen:
>>> import yaml
>>> a = "545.2222"
>>> result = yaml.load(a)
>>> result
545.22220000000004
>>> type(result)
<type 'float'>
>>> b = "31"
>>> result = yaml.load(b)
>>> result
31
>>> type(result)
<type 'int'>
>>> c = "HI"
>>> result = yaml.load(c)
>>> result
'HI'
>>> type(result)
<type 'str'>
Ich benutze diese Funktion für die
import ast
def parse_str(s):
try:
return ast.literal_eval(str(s))
except:
return
Es wird die Zeichenfolge in den Typ umwandeln
value = parse_str('1') # Returns Integer
value = parse_str('1.5') # Returns Float
def get_int_or_float(v):
number_as_float = float(v)
number_as_int = int(number_as_float)
return number_as_int if number_as_float == number_as_int else number_as_float
def num(s):
"""num(s)
num(3),num(3.7)-->3
num('3')-->3, num('3.7')-->3.7
num('3,700')-->ValueError
num('3a'),num('a3'),-->ValueError
num('3e4') --> 30000.0
"""
try:
return int(s)
except ValueError:
try:
return float(s)
except ValueError:
raise ValueError('argument is not a string of number')
Sie müssen berücksichtigen Runden dies richtig zu machen.
d. int (5,1) => 5 int (5.6) => 5 - falsch, sollte 6 sein, so int wir tun (5,6 + 0,5) => 6
def convert(n):
try:
return int(n)
except ValueError:
return float(n + 0.5)
Ich bin überrascht, niemand regex erwähnt, weil manchmal String vorbereitet und normalisiert vor dem Gießen auf Nummer werden müssen
import re
def parseNumber(value, as_int=False):
try:
number = float(re.sub('[^.\-\d]', '', value))
if as_int:
return int(number + 0.5)
else:
return number
except ValueError:
return float('nan') # or None if you wish
Nutzung:
parseNumber('13,345')
> 13345.0
parseNumber('- 123 000')
> -123000.0
parseNumber('99999\n')
> 99999.0
und durch die Art und Weise, etwas zu überprüfen, haben Sie eine Nummer aus:
import numbers
def is_number(value):
return isinstance(value, numbers.Number)
# will work with int, float, long, Decimal
Um in Python verwenden, um den Konstruktor funtions des Typs typisiert, vorbei an die Schnur (oder was auch immer Wert, den Sie versuchen zu werfen) als Parameter.
Zum Beispiel:
>>>float("23.333")
23.333
Hinter den Kulissen Python ruft die Objekte __float__
Methode, die einen Schwimmer Darstellung des Parameters zurückgeben sollte. Dies ist besonders leistungsfähig, wie Sie Ihre eigenen Typen (mit Klassen) definieren können mit einem __float__
Verfahren, so dass es in einen Schwimmer mit Schwimmer gegossen werden kann (myobject).
Dies ist eine korrigierte Version von https://stackoverflow.com/a/33017514/5973334
Dies wird versuchen, eine Zeichenfolge zu analysieren und entweder int
oder float
zurückkehren je nachdem, was die Zeichenfolge darstellt.
Es könnte Parsing Ausnahmen oder ein unerwartetes Verhalten haben.
def get_int_or_float(v):
number_as_float = float(v)
number_as_int = int(number_as_float)
return number_as_int if number_as_float == number_as_int else
number_as_float
Verwendung:
def num(s):
try:
for each in s:
yield int(each)
except ValueError:
yield float(each)
a = num(["123.55","345","44"])
print a.next()
print a.next()
Dies ist die Art, wie ich Pythonic einfiel.
Verwendung:
>>> str_float = "545.2222"
>>> float(str_float)
545.2222
>>> type(_) # Check its type
<type 'float'>
>>> str_int = "31"
>>> int(str_int)
31
>>> type(_) # Check its type
<type 'int'>
Dies ist eine Funktion, die jede object
umwandeln (nicht nur str
) int
oder float
, basierend auf, wenn die tatsächliche Zeichenfolge geliefert sieht aus wie int
oder float
. Weiterhin, wenn es ein Objekt ist, die beide __float
und __int__
Methoden hat, wird standardmäßig __float__
mit
def conv_to_num(x, num_type='asis'):
'''Converts an object to a number if possible.
num_type: int, float, 'asis'
Defaults to floating point in case of ambiguity.
'''
import numbers
is_num, is_str, is_other = [False]*3
if isinstance(x, numbers.Number):
is_num = True
elif isinstance(x, str):
is_str = True
is_other = not any([is_num, is_str])
if is_num:
res = x
elif is_str:
is_float, is_int, is_char = [False]*3
try:
res = float(x)
if '.' in x:
is_float = True
else:
is_int = True
except ValueError:
res = x
is_char = True
else:
if num_type == 'asis':
funcs = [int, float]
else:
funcs = [num_type]
for func in funcs:
try:
res = func(x)
break
except TypeError:
continue
else:
res = x
Hier ist eine andere Interpretation Ihrer Frage (Hinweis: Es ist vage). Es ist möglich, Sie suchen etwas wie folgt aus:
def parseIntOrFloat( aString ):
return eval( aString )
Es funktioniert wie folgt ...
>>> parseIntOrFloat("545.2222")
545.22220000000004
>>> parseIntOrFloat("545")
545
Theoretisch gibt es eine Injection-Schwachstelle. Die Zeichenfolge könnte zum Beispiel "import os; os.abort()"
sein. Ohne Hintergrund auf, wo die Schnur kommt, ist jedoch die Möglichkeit, theoretische Spekulation. Da die Frage vage ist, ist es nicht klar, ob diese Sicherheitsanfälligkeit tatsächlich vorhanden ist oder nicht.