Ich denke, Ihre Lösung ist gut, aber es gibt ist eine korrekte Regexp-Implementierung.
Es scheint eine Menge regexp Hass gegenüber diesen Antworten, die ich denke, ist ungerechtfertigt, regexps kann ziemlich sauber und korrekt und schnell sein. Es hängt wirklich davon ab, was Sie versuchen, zu tun. Die ursprüngliche Frage war, wie man "prüfen kann, ob eine Zeichenkette als Zahl (float) dargestellt werden kann" (wie in Ihrem Titel). Vermutlich möchten Sie den Zahlen-/Fließkommawert verwenden, sobald Sie überprüft haben, dass er gültig ist. In diesem Fall macht Ihr try/except sehr viel Sinn. Aber wenn Sie aus irgendeinem Grund nur überprüfen wollen, dass ein String es un Nummer dann funktioniert ein Regex auch gut, aber es ist schwer, es richtig zu machen. Ich denke, die meisten der Regex-Antworten bisher, zum Beispiel, nicht richtig parsen Zeichenfolgen ohne einen Integer-Teil (wie ".7"), die ein Float ist, soweit Python betrifft. Und das ist etwas schwierig in einer einzelnen Regex zu überprüfen, in der der Bruchteil nicht erforderlich ist. Ich habe zwei Regex eingefügt, um dies zu zeigen.
Es stellt sich die interessante Frage, was eine "Zahl" ist. Schließen Sie "inf" ein, das in Python als Fließkommazahl gültig ist? Oder schließt man Zahlen ein, die zwar "Zahlen" sind, aber vielleicht nicht in Python dargestellt werden können (z. B. Zahlen, die größer sind als der float max).
Es gibt auch Unklarheiten bei der Analyse von Zahlen. Was ist zum Beispiel mit "--20"? Ist das eine "Zahl"? Ist dies eine legale Art, "20" darzustellen? In Python können Sie "var = --20" eingeben und den Wert auf 20 setzen (obwohl dies eigentlich nur möglich ist, weil es als Ausdruck behandelt wird), aber float("--20") funktioniert nicht.
Wie auch immer, ohne weitere Informationen, hier ist eine Regex, die ich glaube, deckt alle ints und Floats wie Python sie parst .
# Doesn't properly handle floats missing the integer part, such as ".7"
SIMPLE_FLOAT_REGEXP = re.compile(r'^[-+]?[0-9]+\.?[0-9]+([eE][-+]?[0-9]+)?$')
# Example "-12.34E+56" # sign (-)
# integer (12)
# mantissa (34)
# exponent (E+56)
# Should handle all floats
FLOAT_REGEXP = re.compile(r'^[-+]?([0-9]+|[0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?$')
# Example "-12.34E+56" # sign (-)
# integer (12)
# OR
# int/mantissa (12.34)
# exponent (E+56)
def is_float(str):
return True if FLOAT_REGEXP.match(str) else False
Einige Beispiel-Testwerte:
True <- +42
True <- +42.42
False <- +42.42.22
True <- +42.42e22
True <- +42.42E-22
False <- +42.42e-22.8
True <- .42
False <- 42nope
Die Ausführung des Benchmarking-Codes in @ron-reiter's Antwort zeigt, dass diese Regex tatsächlich schneller ist als die normale Regex und viel schneller mit schlechten Werten umgeht als die Ausnahme, was durchaus sinnvoll ist. Ergebnisse:
check_regexp with good floats: 18.001921
check_regexp with bad floats: 17.861423
check_regexp with strings: 17.558862
check_correct_regexp with good floats: 11.04428
check_correct_regexp with bad floats: 8.71211
check_correct_regexp with strings: 8.144161
check_replace with good floats: 6.020597
check_replace with bad floats: 5.343049
check_replace with strings: 5.091642
check_exception with good floats: 5.201605
check_exception with bad floats: 23.921864
check_exception with strings: 23.755481
101 Stimmen
Was ist falsch an Ihrer derzeitigen Lösung? Sie ist kurz, schnell und lesbar.
7 Stimmen
Und Sie müssen nicht nur True oder False zurückgeben. Sie können stattdessen den Wert entsprechend modifiziert zurückgeben - zum Beispiel könnten Sie dies verwenden, um Nicht-Zahlen in Anführungszeichen zu setzen.
10 Stimmen
Wäre es nicht besser, im Falle einer erfolgreichen Konvertierung das Ergebnis von float(s) zurückzugeben? Sie haben immer noch die Erfolgsprüfung (Ergebnis ist False) und Sie haben die Umwandlung, die Sie wahrscheinlich sowieso wollen.
0 Stimmen
Thruston - Ich verstehe, was Sie meinen, aber dann ist die Prüfung nicht mehr so einfach.
12 Stimmen
Auch wenn diese Frage schon älter ist, wollte ich nur sagen, dass dies ein eleganter Weg ist, der dokumentiert ist als EAFP . Das ist wahrscheinlich die beste Lösung für diese Art von Problem.
2 Stimmen
Das scheint in Ordnung zu sein, es sei denn, Sie validieren die Eingaben eines Benutzers, da locale.atoi("0,1,00") 100.... ergibt.
0 Stimmen
Sehr nützliche Funktion. Darüber hinaus, wenn Sie Raum, wie 1e + 2, etc. zulassen wollen, dann muss diese Funktion geändert werden.
0 Stimmen
Wenn Sie nicht wissen, ob es sich bei dem Eingabewert um eine Zeichenkette handelt, können Sie auch einen TypeError
2 Stimmen
pythoncentral.io/ würde helfen.
0 Stimmen
Gibt das Ergebnis von
float(s)
bei Erfolg, oderNone
, bei Fail. Dann erhalten Sie das True/False-Verhalten und können das Ergebnis direkt verwenden.0 Stimmen
Verwandt: Float/Double-Wert extrahieren
10 Stimmen
Nicht gibt das Ergebnis von float(s) oder None bei Fail zurück. Wenn Sie es dann als
x = float('0.00'); if x: use_float(x);
haben Sie jetzt einen Fehler in Ihrem Code. Wahrheitsgemäße Werte sind der Grund dafür, dass diese Funktionen eine Ausnahme auslösen und nicht zurückgebenNone
an erster Stelle. Eine bessere Lösung ist es, die Hilfsfunktion zu vermeiden und den Aufruf von float in einetry catch
wenn Sie es benutzen wollen.0 Stimmen
Dies ist ein Teil des Problems, das in dem Beitrag stackoverflow.com/questions/36903462/adding-numbers-in-a-string/
4 Stimmen
Achtung: Das Snippet sagt aus, dass jede Objekt, das automatisch wirft zu float ist eine Zahl, und das könnte irreführend sein. Zum Beispiel kann eine einfache bool ist eine Zahl, da float(True) eine gültige 1,0 zurückgibt.
0 Stimmen
Nicht langsam. int(s) oder float(s) ist wahrscheinlich fast so schnell wie das, was der Python-Interpreter für solche Dinge verwendet und kann sogar etwas C-Code darunter haben. In [17]: time_it(int, '333', count=1) Out[17]: 4.0531158447265625e-06 Ziemlich schnell.
0 Stimmen
Wahrscheinlich möchten Sie den ValueError-Teil loswerden, da dieser sonst eine Ausnahme auslöst, wenn er eine Liste / ein Diktat als Eingabe erhält
0 Stimmen
@Colonel Panic es ist auch langsam
2 Stimmen
Der langsame Teil ist NICHT der Float(a). Der langsame Teil ist die Ausnahme throw/catch. Wie jeder gute Programmierer weiß: VERWENDEN SIE NIEMALS AUSNAHMEN FÜR DEN NORMALEN CODE-WEG. Der OP hat das nicht spezifiziert, also denke ich, dass wir davon ausgehen sollten, dass nicht-numerische Eingaben "normal" für diese Funktion sind. Ist es in Python üblich, Ausnahmen als Teil des normalen Codeflusses zu verwenden? @SamanthaAtkins
0 Stimmen
Warum nicht folgen lazy Überprüfung Muster? davon ausgehen, dass das Objekt ein Float ist und versuchen Sie die Operation und fangen eine Ausnahme, protokollieren Sie es und dann gießen Sie es zu Float und reattempt.