Wie überprüfe ich, ob ein String eine Zahl darstellt (float oder int)?

Lesezeit: 9 Minuten

Benutzer-Avatar
Daniel Goldberg

Wie überprüfe ich, ob eine Zeichenfolge einen numerischen Wert in Python darstellt?

def is_number(s):
    try:
        float(s)
        return True
    except ValueError:
        return False

Das obige funktioniert, aber es scheint klobig zu sein.


Wenn das, was Sie testen, aus Benutzereingaben stammt, ist es das still ein Faden auch wenn es repräsentiert ein int oder ein float. Siehe Wie kann ich Eingaben als Zahlen lesen? zum Konvertieren der Eingabe, und Fragen des Benutzers nach einer Eingabe, bis er eine gültige Antwort gibt, um sicherzustellen, dass die Eingabe eine darstellt int oder float (oder andere Anforderungen), bevor Sie fortfahren.

  • Was ist falsch an Ihrer aktuellen Lösung? Es ist kurz, schnell und lesbar.

    – Oberst Panik

    21. März 2013 um 22:52 Uhr


  • Und Sie müssen nicht nur True oder False zurückgeben. Sie können stattdessen den Wert entsprechend modifiziert zurückgeben – Sie könnten dies beispielsweise verwenden, um Nicht-Zahlen in Anführungszeichen zu setzen.

    – Thruston

    24. Mai 2013 um 21:33 Uhr

  • Wäre es nicht besser, das Ergebnis von Float(s) im Falle einer erfolgreichen Konvertierung zurückzugeben? Sie haben immer noch die Erfolgsprüfung (Ergebnis ist False) und Sie HABEN tatsächlich die Konvertierung, die Sie wahrscheinlich sowieso wollen.

    – Jiminion

    25. Juli 2013 um 14:40 Uhr

  • Auch wenn diese Frage älter ist, wollte ich nur sagen, dass dies ein eleganter Weg ist, der als dokumentiert ist EAFP. Also wahrscheinlich die beste Lösung für diese Art von Problem.

    – Thiruvenkadam

    7. Oktober 2013 um 15:42 Uhr


  • Nicht gibt das Ergebnis von Float(s) oder None bei Fehlschlag zurück. wenn Sie es dann als verwenden x = float('0.00'); if x: use_float(x); Sie haben jetzt einen Fehler in Ihrem Code. Wahrheitswerte sind der Grund, warum diese Funktionen eine Ausnahme auslösen, anstatt zurückzukehren None an erster Stelle. Eine bessere Lösung besteht darin, die Utility-Funktion einfach zu vermeiden und den Aufruf von Float in a einzuschließen try catch wenn Sie es verwenden möchten.

    – Oval

    5. Januar 2016 um 7:31 Uhr


Benutzer-Avatar
S. Lott

Was nicht nur hässlich und langsam ist

Beides würde ich bestreiten.

Ein Regex oder eine andere String-Parsing-Methode wäre hässlicher und langsamer.

Ich bin mir nicht sicher, ob irgendetwas viel schneller sein könnte als das oben Genannte. Es ruft die Funktion auf und kehrt zurück. Try/Catch führt nicht zu viel Overhead, da die häufigste Ausnahme ohne eine umfassende Suche nach Stack-Frames abgefangen wird.

Das Problem ist, dass jede numerische Konvertierungsfunktion zwei Arten von Ergebnissen hat

  • Eine Nummer, wenn die Nummer gültig ist
  • Ein Statuscode (z. B. via errno) oder eine Ausnahme, um anzuzeigen, dass keine gültige Nummer geparst werden konnte.

C (als Beispiel) umgeht dies auf verschiedene Weise. Python legt es klar und deutlich dar.

Ich denke, Ihr Code dafür ist perfekt.

  • Ich denke nicht, dass der Code perfekt ist (aber ich denke, er ist sehr nah dran): Es ist üblicher zu sagen nur der Teil wird in der “getestet”. try Klausel, also würde ich die setzen return True in einem (n else Klausel des try. Einer der Gründe ist, dass ich mit dem Code in der Frage, wenn ich ihn überprüfen müsste, überprüfen müsste, ob die zweite Anweisung in der try -Klausel kann keinen ValueError auslösen: Zugegeben, dies erfordert nicht zu viel Zeit oder Gehirnleistung, aber warum sollten Sie eine verwenden, wenn keine benötigt wird?

    – Eric O. Lebigot

    5. Juli 2013 um 8:21 Uhr


  • Die Antwort scheint überzeugend, aber ich frage mich, warum sie nicht sofort einsatzbereit ist … Ich werde dies kopieren und auf jeden Fall verwenden.

    – Salbei

    28. Dezember 2013 um 23:40 Uhr

  • Wie schrecklich. Wie wäre es, wenn mir die Nummer egal ist ist nur dass es eine Zahl ist (was mich hierher geführt hat)? Anstelle einer 1-Linie IsNumeric() Ich ende entweder mit einem Versuch/Fang oder einem anderen, der einen Versuch/Fang umschließt. Pfui

    – Basic

    10. März 2014 um 11:22 Uhr


  • Es wird nicht “out of the box” geliefert, weil if is_number(s): x = float(x) else: // fail ist die gleiche Anzahl von Codezeilen wie die try: x = float(x) catch TypeError: # fail. Diese Nutzenfunktion ist eine völlig unnötige Abstraktion.

    – Oval

    5. Januar 2016 um 7:34 Uhr


  • Aber Abstraktion ist der springende Punkt bei Bibliotheken. Eine ‘isNumber’-Funktion (in jeder Sprache) zu haben, hilft enorm, weil Sie sie direkt in if-Anweisungen einbauen können und weitaus besser lesbaren und wartbaren Code haben, der sich auf try-catch-Blöcke stützt. Wenn Sie den Code mehr als einmal in mehr als einer Klasse/einem Modul verwenden müssen, haben Sie außerdem mehr Codezeilen verwendet, als eine eingebaute Funktion hätte.

    – Jam Engulfer

    18. März 2016 um 11:19 Uhr

  • für schöne Diagramme +1. Ich habe Benchmarks und Grafiken gesehen, das ganze TL;DR-Ding wurde klar und intuitiv.

    – jchuks

    18. November 2016 um 18:35 Uhr

  • Diese Methode verarbeitet keine negativen Zahlen (Bindestriche). Ich würde empfehlen, nur die Float-Methode zu verwenden, da sie weniger fehleranfällig ist und jedes Mal funktioniert.

    – Seeigel

    10. April 2019 um 15:55 Uhr

  • Wichtig zu beachten ist, dass selbst unter der Annahme, dass es keinen Bindestrich geben kann, die Methode replace-isdigit nur für Nicht-Zahlen schneller ist (falsches Ergebnis), während die try-except-Methode für Zahlen schneller ist (wahres Ergebnis). Wenn die meisten Ihrer Eingaben gültige Eingaben sind, sind Sie mit der Try-Außer-Lösung besser dran!

    – Markus von Broady

    24. April 2019 um 12:43 Uhr


  • Funktioniert nicht bei Exponentialschreibweise wie '1.5e-9' oder auf Negativen.

    – EL_DON

    17. Oktober 2019 um 19:03 Uhr

  • Brillant, Abgesehen von den offensichtlichen Vorbehalten falscher Negativer für Potenzierung und Negative – die Sie trivialerweise durch einfaches Verketten korrigieren können s.replace() Anrufe. Zum Beispiel, s.replace('.','',1).replace('e-','',1).replace('e','',1).isdigit() übernimmt Potenzierung. Um dann mit Negativen umzugehen, entfernen Sie einfach das erste Zeichen, wenn es sich um einen Bindestrich handelt. Zum Beispiel, s.lstrip('-').replace('.','',1).replace('e-','',1).replace('e','',1).isdigit(). Ja, ich habe diesen Einzeiler ausführlich getestet und kann bestätigen, dass er sich wie erwartet verhält.

    – Cecil Curry

    25. September 2020 um 0:59 Uhr

Es gibt eine Ausnahme, die Sie vielleicht berücksichtigen möchten: die Zeichenfolge „NaN“.

Wenn Sie möchten, dass is_number FALSE für ‘NaN’ zurückgibt, funktioniert dieser Code nicht, da Python ihn in seine Darstellung einer Zahl konvertiert, die keine Zahl ist (sprechen Sie über Identitätsprobleme):

>>> float('NaN')
nan

Ansonsten sollte ich Ihnen eigentlich für das Stück Code danken, das ich jetzt ausgiebig verwende. 🙂

G.

  • Eigentlich, NaN könnte ein guter Wert für die Rückgabe sein (anstatt False), wenn der übergebene Text tatsächlich keine Darstellung einer Zahl ist. Es zu überprüfen ist ziemlich mühsam (Python’s float type benötigt eigentlich eine Methode dafür), aber Sie können es in Berechnungen verwenden, ohne einen Fehler zu erzeugen, und müssen nur das Ergebnis überprüfen.

    – irgendwie

    10. Juni 2011 um 17:50 Uhr

  • Eine weitere Ausnahme ist die Zeichenfolge 'inf'. Entweder inf oder NaN kann auch mit vorangestellt werden + oder - und trotzdem angenommen werden.

    – agf

    22. Mai 2012 um 23:10 Uhr

  • Wenn Sie False für NaN und Inf zurückgeben möchten, ändern Sie die Zeile in x = float(s); gib (x == x) und (x – 1 != x) zurück. Dies sollte für alle Floats außer Inf und NaN True zurückgeben

    – RyanN

    15. März 2013 um 20:29 Uhr


  • x-1 == x gilt für große Schwimmer kleiner als inf. Ab Python 3.2 können Sie verwenden math.isfinite um auf Zahlen zu testen, die weder NaN noch unendlich sind, oder beides zu überprüfen math.isnan und math.isinf davor.

    – Steve Jessop

    22. Januar 2014 um 18:39 Uhr


Benutzer-Avatar
David C

Wie wäre es damit:

'3.14'.replace('.','',1).isdigit()

was nur dann wahr zurückgibt, wenn es ein oder kein ‘.’ in der Ziffernfolge.

'3.14.5'.replace('.','',1).isdigit()

wird falsch zurückgegeben

Bearbeiten: Ich habe gerade einen anderen Kommentar gesehen … Hinzufügen eines .replace(badstuff,'',maxnum_badstuff) für andere Fälle kann getan werden. wenn Sie Salz und keine willkürlichen Gewürze passieren (ref:xkcd#974) das wird gut gehen 😛

  • Eigentlich, NaN könnte ein guter Wert für die Rückgabe sein (anstatt False), wenn der übergebene Text tatsächlich keine Darstellung einer Zahl ist. Es zu überprüfen ist ziemlich mühsam (Python’s float type benötigt eigentlich eine Methode dafür), aber Sie können es in Berechnungen verwenden, ohne einen Fehler zu erzeugen, und müssen nur das Ergebnis überprüfen.

    – irgendwie

    10. Juni 2011 um 17:50 Uhr

  • Eine weitere Ausnahme ist die Zeichenfolge 'inf'. Entweder inf oder NaN kann auch mit vorangestellt werden + oder - und trotzdem angenommen werden.

    – agf

    22. Mai 2012 um 23:10 Uhr

  • Wenn Sie False für NaN und Inf zurückgeben möchten, ändern Sie die Zeile in x = float(s); gib (x == x) und (x – 1 != x) zurück. Dies sollte für alle Floats außer Inf und NaN True zurückgeben

    – RyanN

    15. März 2013 um 20:29 Uhr


  • x-1 == x gilt für große Schwimmer kleiner als inf. Ab Python 3.2 können Sie verwenden math.isfinite um auf Zahlen zu testen, die weder NaN noch unendlich sind, oder beides zu überprüfen math.isnan und math.isinf davor.

    – Steve Jessop

    22. Januar 2014 um 18:39 Uhr


Aktualisiert, nachdem Alfe darauf hingewiesen hat, dass Sie den Float nicht separat prüfen müssen, da komplexe beide behandelt:

def is_number(s):
    try:
        complex(s) # for int, long, float and complex
    except ValueError:
        return False

    return True

Zuvor gesagt: In einigen seltenen Fällen müssen Sie möglicherweise auch nach komplexen Zahlen suchen (z. B. 1+2i), die nicht durch einen Float dargestellt werden können:

def is_number(s):
    try:
        float(s) # for int, long and float
    except ValueError:
        try:
            complex(s) # for complex
        except ValueError:
            return False

    return True

  • Ich stimme dir nicht zu. Das ist bei normaler Verwendung SEHR unwahrscheinlich, und Sie sollten besser einen is_complex_number() -Aufruf erstellen, wenn Sie sie verwenden, anstatt einen Aufruf mit einer zusätzlichen Operation für eine Wahrscheinlichkeit von 0,0001% einer Fehlbedienung zu belasten.

    – Jiminion

    25. Juli 2013 um 14:43 Uhr

  • Sie können die abziehen float() Zeug vollständig und überprüfen Sie einfach für die complex() Aufruf zum Erfolg. Alles durch analysiert float() kann geparst werden complex().

    – Alfe

    22. April 2016 um 9:31 Uhr

  • Diese Funktion gibt die NaNs- und Inf-Werte von Pandas als numerische Werte zurück.

    – fixer

    29. Mai 2016 um 11:51 Uhr

  • complex('(01989)') wird zurückkehren (1989+0j). Aber float('(01989)') wird versagen. Also denke ich mit complex ist keine gute Idee.

    – plhn

    20. Dezember 2018 um 15:19 Uhr

  • Huch. Bizarr das complex() akzeptiert (– und )-begrenzte Syntax – vermutlich, um die zusammengesetzte Vektoraddition in der imaginären Ebene zu berücksichtigen, die komplexen Zahlen zugrunde liegt, aber immer noch. Wie @plhn vorschlägt, mit complex() lädt hier zu Fehlalarmen ein. Tun Sie dies nicht im Produktionscode. Ganz ehrlich, s.lstrip('-').replace('.','',1).replace('e-','',1).replace('e','',1).isdigit() bleibt für die meisten Anwendungsfälle die optimale Lösung.

    – Cecil Curry

    25. September 2020 um 1:07 Uhr


1383340cookie-checkWie überprüfe ich, ob ein String eine Zahl darstellt (float oder int)?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy