Wie kann ich in Python einen numerischen String wie "545.2222"
auf den entsprechenden Gleitkommawert 545.2222
parsen? Oder analysieren Sie die Zeichenfolge "31"
in eine Ganzzahl, 31
?
Ich möchte nur wissen, wie man ein floatstr
zu einem float
und (separat) ein intstr
zu einem int
.
>>> a = "545.2222"
>>> float(a)
545.22220000000004
>>> int(float(a))
545
def num(s):
try:
return int(s)
except ValueError:
return float(s)
def is_float(value):
try:
float(value)
return True
except:
return False
Ein längerer und genauerer Name für diese Funktion könnte sein: is_convertible_to_float(value)
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 glauben zu wissen, was Zahlen sind? Du bist nicht so gut wie du denkst! Keine große Überraschung.
Wenn Sie auf diese Weise breite Ausnahmen abfangen, Kanarienvögel töten und die Ausnahme verschlingen, besteht eine geringe Wahrscheinlichkeit, dass ein gültiger float als String false zurückgibt. Die Codezeile float(...)
kann aus tausend Gründen fehlschlagen, die nichts mit dem Inhalt der Zeichenfolge zu tun haben. Wenn Sie jedoch lebenswichtige Software in einer Prototypensprache wie Python schreiben, haben Sie viel größere Probleme.
Dies ist eine weitere Methode, die hier erwähnt werden sollte ast.literal_eval :
Dies kann zum sicheren Auswerten von Zeichenfolgen verwendet werden, die Python Ausdrücke aus nicht vertrauenswürdigen Quellen enthalten, ohne dass die Werte selbst analysiert werden müssen.
Das heißt, eine sichere "Bewertung"
>>> import ast
>>> ast.literal_eval("545.2222")
545.2222
>>> ast.literal_eval("31")
31
float(x) if '.' in x else int(x)
Sie sollten die Möglichkeit von Kommas in der Zeichenfolgendarstellung einer Zahl in Betracht ziehen, für Fälle wie float("545,545.2222")
, die eine Ausnahme auslösen. Verwenden Sie stattdessen Methoden in locale
, um die Zeichenfolgen in Zahlen zu konvertieren und Kommas korrekt zu interpretieren. Die locale.atof
-Methode wird in einem Schritt in ein Float konvertiert, sobald das Gebietsschema für die gewünschte Nummernkonvention festgelegt wurde.
Beispiel 1 - US-amerikanische Nummernkonventionen
In den USA und Großbritannien können Kommas als Tausendertrennzeichen verwendet werden. In diesem Beispiel mit amerikanischem Gebietsschema wird das Komma ordnungsgemäß als Trennzeichen 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 Nummernkonventionen
In den meisten Ländern der Welt werden Kommas anstelle von Punkten für Dezimalzeichen verwendet. In diesem Beispiel mit französischem Gebietsschema 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
Die Methode locale.atoi
ist ebenfalls verfügbar, das Argument sollte jedoch eine Ganzzahl sein.
Wenn Sie keine Abneigung gegen Module von Drittanbietern haben, können Sie das Modul fastnumbers ausprobieren. Es bietet eine Funktion mit dem Namen fast_real , die genau das tut, was diese Frage verlangt, und dies 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
Die Benutzer codelogic und harley sind korrekt, aber denken Sie daran, dass Sie int ("545") aufrufen können, wenn Sie wissen, dass die Zeichenfolge eine Ganzzahl ist (z. B. 545) Gießen, um zu schweben.
Wenn sich Ihre Zeichenfolgen in einer Liste befinden, können Sie auch die Kartenfunktion verwenden.
>>> x = ["545.0", "545.6", "999.2"]
>>> map(float, x)
[545.0, 545.60000000000002, 999.20000000000005]
>>>
Es ist nur gut, wenn sie alle vom selben Typ sind.
Die Frage scheint ein bisschen alt. Aber lassen Sie mich eine Funktion vorschlagen, parseStr, die etwas Ähnliches erzeugt, dh Integer oder Float zurückgibt, und wenn eine gegebene Zeichenfolge ASCII nicht in keine konvertiert werden kann, wird sie unberührt zurückgegeben. Der Code kann natürlich angepasst werden, um 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'
Wie kann ich in Python eine numerische Zeichenfolge wie "545.2222" auf den entsprechenden Gleitkommawert (542.2222) parsen? Oder parsen Sie die Zeichenfolge "31" in eine Ganzzahl, 31? Ich möchte nur wissen, wie eine float-Zeichenfolge in eine float-Zeichenfolge und (separat) eine int-Zeichenfolge in eine int-Zeichenfolge umgewandelt wird.
Es ist gut, dass Sie darum bitten, dies separat zu tun. Wenn Sie sie mischen, können Sie sich später auf Probleme einstellen. Die einfache Antwort lautet:
"545.2222"
um zu schweben:
>>> float("545.2222")
545.2222
"31"
zu einer ganzen Zahl:
>>> int("31")
31
Konvertierungen von verschiedenen Basen, und Sie sollten die Basis im Voraus kennen (10 ist die Standardeinstellung). Beachten Sie, dass Sie ihnen das Präfix voranstellen können, was Python für seine Literale erwartet (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 die Basis nicht im Voraus kennen, aber wissen, dass sie das richtige Präfix haben, kann Python dies für Sie herleiten, wenn Sie 0
als Basis übergeben:
>>> int("0b11111", 0)
31
>>> int('0o37', 0)
31
>>> int('0x1f', 0)
31
Wenn Ihre Motivation darin besteht, dass Ihr eigener Code fest codierte spezifische Werte eindeutig darstellt, müssen Sie möglicherweise nicht von den Basen aus konvertieren - Sie können Python dies automatisch mit der richtigen Syntax für Sie tun lassen.
Sie können die Präfixe apropos verwenden, um eine automatische Konvertierung in Ganzzahlen mit den folgenden Literalen zu erhalten. Diese gelten für Python 2 und 3:
Binär, Präfix 0b
>>> 0b11111
31
Oktal, Präfix 0o
>>> 0o37
31
Hexadezimal, Präfix 0x
>>> 0x1f
31
Dies kann hilfreich sein, wenn Sie Binärflags, Dateiberechtigungen im Code oder hexadezimale Werte für Farben beschreiben. Beachten Sie beispielsweise 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
Wenn Sie in Python 2 eine Ganzzahl sehen, die mit einer 0 beginnt, ist dies eine (veraltete) Oktalsyntax.
>>> 037
31
Es ist schlecht, weil es so aussieht, als ob der Wert 37
sein sollte. In Python 3 wird nun SyntaxError
ausgelöst:
>>> 037
File "<stdin>", line 1
037
^
SyntaxError: invalid token
Konvertieren Sie Ihre Python 2 Oktale in Oktale, die sowohl in 2 als auch in 3 mit dem 0o
-Präfix funktionieren:
>>> 0o37
31
float("545.2222")
und int(float("545.2222"))
Ich benutze diese Funktion dafür
import ast
def parse_str(s):
try:
return ast.literal_eval(str(s))
except:
return
Die Zeichenfolge wird in den Typ konvertiert
value = parse_str('1') # Returns Integer
value = parse_str('1.5') # Returns Float
Mit dem Parser YAML können Sie herausfinden, um welchen Datentyp es sich bei Ihrer Zeichenfolge handelt. Verwenden Sie yaml.load()
, und testen Sie dann mit type(result)
den Typ:
>>> 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'>
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 die Rundung berücksichtigen, um dies richtig zu tun.
Das heißt int (5.1) => 5 int (5.6) => 5 - falsch, sollte 6 sein, also machen wir int (5.6 + 0.5) => 6
def convert(n):
try:
return int(n)
except ValueError:
return float(n + 0.5)
Ich bin überrascht, dass niemand Regex erwähnt hat, da die Zeichenfolge manchmal vorbereitet und normalisiert werden muss, bevor sie auf die Nummer geworfen wird
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
verwendungszweck:
parseNumber('13,345')
> 13345.0
parseNumber('- 123 000')
> -123000.0
parseNumber('99999\n')
> 99999.0
übrigens, um zu überprüfen, ob Sie eine Nummer haben:
import numbers
def is_number(value):
return isinstance(value, numbers.Number)
# will work with int, float, long, Decimal
Verwenden Sie für die Typumwandlung in python die Konstruktorfunktionen des Typs und übergeben Sie den String (oder den Wert, den Sie umwandeln möchten) als Parameter.
Zum Beispiel:
>>>float("23.333")
23.333
Hinter den Kulissen ruft python die Methode objects __float__
auf, die eine Float-Darstellung des Parameters zurückgeben soll. Dies ist besonders leistungsstark, da Sie Ihre eigenen Typen (mithilfe von Klassen) mit einer __float__
-Methode definieren können, sodass sie mit float (myobject) in ein Float umgewandelt werden können.
Python bietet diese große Flexibilität beim Parsen in einem Liner.
str = "545.2222"
print ("int: ", + int(float(a)))
print ("float: ", +(float(a)))
Dies ist eine korrigierte Version von https://stackoverflow.com/a/33017514/5973334
Dadurch wird versucht, eine Zeichenfolge zu analysieren, und es wird entweder int
oder float
zurückgegeben, je nachdem, was die Zeichenfolge darstellt. Es können Parsing-Ausnahmen auftreten oder nerwartetes Verhalten .
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
Sie können str()
verwenden, um eine Variable in einen String umzuwandeln, int()
, um String-Ganzzahlen in Ganzzahlen umzuwandeln, und float()
, um String-Gleitkommazahlen in Gleitkommazahlen umzuwandeln.
str_to_float = float("545.2222")
str_to_int = int("31")
Verwenden:
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 der pythonischste Weg, den ich finden konnte.
Dies ist eine Funktion, die jeden object
(nicht nur str
) in int
oder float
konvertiert, je nachdem, ob der tatsächlich angegebene String sieht aus wie = int
oder float
. Wenn es sich um ein Objekt handelt, das über die Methoden __float
und __int__
verfügt, wird standardmäßig __float__
verwendet.
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
Verwenden:
>>> 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'>