Kann man irgendwie feststellen, ob ein String steht für eine ganze Zahl (z.B., '3'
, '-17'
aber nicht '3.14'
o 'asfasfas'
) Ohne Verwendung eines try/except-Mechanismus?
is_int('3.14') == False
is_int('-7') == True
Kann man irgendwie feststellen, ob ein String steht für eine ganze Zahl (z.B., '3'
, '-17'
aber nicht '3.14'
o 'asfasfas'
) Ohne Verwendung eines try/except-Mechanismus?
is_int('3.14') == False
is_int('-7') == True
Mit positiven ganzen Zahlen könnten Sie verwenden .isdigit
:
>>> '16'.isdigit()
True
Es funktioniert allerdings nicht mit negativen ganzen Zahlen. Sie könnten Folgendes versuchen:
>>> s = '-17'
>>> s.startswith('-') and s[1:].isdigit()
True
es funktioniert nicht mit '16.0'
Format, das ähnlich ist wie int
Gießen in diesem Sinne.
editar :
def check_int(s):
if s[0] in ('-', '+'):
return s[1:].isdigit()
return s.isdigit()
Wenn Sie wirklich nur genervt sind von der Verwendung von try/except
s überall zu finden sind, schreiben Sie bitte einfach eine Hilfsfunktion:
def RepresentsInt(s):
try:
int(s)
return True
except ValueError:
return False
>>> print RepresentsInt("+123")
True
>>> print RepresentsInt("10.0")
False
Es wird VIEL mehr Code sein, um alle Zeichenketten, die Python als ganze Zahlen betrachtet, genau abzudecken. Ich sage, nur pythonic auf dieser einen sein.
Wissen Sie, ich habe festgestellt (und ich habe dies immer wieder getestet), dass try/except nicht so gut funktioniert, aus welchem Grund auch immer. Ich probiere häufig verschiedene Methoden aus, und ich glaube nicht, dass ich jemals eine Methode gefunden habe, bei der try/except die beste der getesteten Methoden ist, sondern es scheint mir, dass diese Methoden in der Regel nahe an der schlechtesten, wenn nicht sogar der schlechtesten sind. Nicht in jedem Fall, aber in vielen Fällen. Ich weiß, dass viele Leute sagen, es sei der "pythonische" Weg, aber das ist ein Bereich, in dem ich mit ihnen nicht übereinstimme. Für mich ist es weder sehr performant noch sehr elegant, daher neige ich dazu, es nur für das Auffangen und Melden von Fehlern zu verwenden.
Ich wollte mich darüber beschweren, dass PHP, Perl, Ruby, C und sogar die verdammte Shell einfache Funktionen zum Testen einer Zeichenkette auf Integer-Haftigkeit haben, aber die Sorgfaltspflicht beim Überprüfen dieser Annahmen hat mich gestört! Offenbar ist dieser Mangel eine weit verbreitete Krankheit.
Hier ist eine schnelle und schmutzige Bearbeitung von Brunos Beitrag:
import sys, time, re
g_intRegex = re.compile(r"^([+-]?[1-9]\d*|0)$")
testvals = [
# integers
0, 1, -1, 1.0, -1.0,
'0', '0.','0.0', '1', '-1', '+1', '1.0', '-1.0', '+1.0', '06',
# non-integers
'abc 123',
1.1, -1.1, '1.1', '-1.1', '+1.1',
'1.1.1', '1.1.0', '1.0.1', '1.0.0',
'1.0.', '1..0', '1..',
'0.0.', '0..0', '0..',
'one', object(), (1,2,3), [1,2,3], {'one':'two'},
# with spaces
' 0 ', ' 0.', ' .0','.01 '
]
def isInt_try(v):
try: i = int(v)
except: return False
return True
def isInt_str(v):
v = str(v).strip()
return v=='0' or (v if v.find('..') > -1 else v.lstrip('-+').rstrip('0').rstrip('.')).isdigit()
def isInt_re(v):
import re
if not hasattr(isInt_re, 'intRegex'):
isInt_re.intRegex = re.compile(r"^([+-]?[1-9]\d*|0)$")
return isInt_re.intRegex.match(str(v).strip()) is not None
def isInt_re2(v):
return g_intRegex.match(str(v).strip()) is not None
def check_int(s):
s = str(s)
if s[0] in ('-', '+'):
return s[1:].isdigit()
return s.isdigit()
def timeFunc(func, times):
t1 = time.time()
for n in range(times):
for v in testvals:
r = func(v)
t2 = time.time()
return t2 - t1
def testFuncs(funcs):
for func in funcs:
sys.stdout.write( "\t%s\t|" % func.__name__)
print()
for v in testvals:
if type(v) == type(''):
sys.stdout.write("'%s'" % v)
else:
sys.stdout.write("%s" % str(v))
for func in funcs:
sys.stdout.write( "\t\t%s\t|" % func(v))
sys.stdout.write("\r\n")
if __name__ == '__main__':
print()
print("tests..")
testFuncs((isInt_try, isInt_str, isInt_re, isInt_re2, check_int))
print()
print("timings..")
print("isInt_try: %6.4f" % timeFunc(isInt_try, 10000))
print("isInt_str: %6.4f" % timeFunc(isInt_str, 10000))
print("isInt_re: %6.4f" % timeFunc(isInt_re, 10000))
print("isInt_re2: %6.4f" % timeFunc(isInt_re2, 10000))
print("check_int: %6.4f" % timeFunc(check_int, 10000))
Hier sind die Ergebnisse des Leistungsvergleichs:
timings..
isInt_try: 0.6426
isInt_str: 0.7382
isInt_re: 1.1156
isInt_re2: 0.5344
check_int: 0.3452
Eine C-Methode könnte es einmal durchscannen, und fertig. Eine C-Methode, die die Zeichenfolge einmal durch scannt, wäre das Richtige zu tun, denke ich.
EDITAR:
Ich habe den obigen Code aktualisiert, um in Python 3.5 zu funktionieren und die check_int-Funktion aus der aktuell meistgewählten Antwort einzuschließen und die aktuell beliebteste Regex zu verwenden, die ich zum Testen auf Integer-Haftigkeit finden kann. Diese Regex lehnt Zeichenketten wie 'abc 123' ab. Ich habe 'abc 123' als Testwert hinzugefügt.
Es ist für mich sehr interessant, an dieser Stelle festzustellen, dass KEINE der getesteten Funktionen, einschließlich der try-Methode, der beliebten check_int-Funktion und der beliebtesten Regex zum Testen auf Integer-Haftigkeit, die richtigen Antworten für alle Testwerte zurückgibt (je nachdem, was man für die richtigen Antworten hält; siehe die Testergebnisse unten).
Die eingebaute Funktion int() schneidet den Nachkommateil einer Fließkommazahl stillschweigend ab und gibt den ganzzahligen Teil vor dem Dezimalwert zurück, es sei denn, die Fließkommazahl wird zunächst in eine Zeichenkette umgewandelt.
Die Funktion check_int() gibt für Werte wie 0.0 und 1.0 (die technisch gesehen ganze Zahlen sind) false und für Werte wie '06' true zurück.
Hier sind die aktuellen (Python 3.5) Testergebnisse:
isInt_try | isInt_str | isInt_re | isInt_re2 | check_int |
0 True | True | True | True | True |
1 True | True | True | True | True |
-1 True | True | True | True | True |
1.0 True | True | False | False | False |
-1.0 True | True | False | False | False |
'0' True | True | True | True | True |
'0.' False | True | False | False | False |
'0.0' False | True | False | False | False |
'1' True | True | True | True | True |
'-1' True | True | True | True | True |
'+1' True | True | True | True | True |
'1.0' False | True | False | False | False |
'-1.0' False | True | False | False | False |
'+1.0' False | True | False | False | False |
'06' True | True | False | False | True |
'abc 123' False | False | False | False | False |
1.1 True | False | False | False | False |
-1.1 True | False | False | False | False |
'1.1' False | False | False | False | False |
'-1.1' False | False | False | False | False |
'+1.1' False | False | False | False | False |
'1.1.1' False | False | False | False | False |
'1.1.0' False | False | False | False | False |
'1.0.1' False | False | False | False | False |
'1.0.0' False | False | False | False | False |
'1.0.' False | False | False | False | False |
'1..0' False | False | False | False | False |
'1..' False | False | False | False | False |
'0.0.' False | False | False | False | False |
'0..0' False | False | False | False | False |
'0..' False | False | False | False | False |
'one' False | False | False | False | False |
<obj..> False | False | False | False | False |
(1, 2, 3) False | False | False | False | False |
[1, 2, 3] False | False | False | False | False |
{'one': 'two'} False | False | False | False | False |
' 0 ' True | True | True | True | False |
' 0.' False | True | False | False | False |
' .0' False | False | False | False | False |
'.01 ' False | False | False | False | False |
Gerade habe ich versucht, diese Funktion hinzuzufügen:
def isInt_float(s):
try:
return float(str(s)).is_integer()
except:
return False
Es funktioniert fast so gut wie check_int (0.3486) und gibt wahr für Werte wie 1.0 und 0.0 und +1.0 und 0. und .0 und so weiter. Aber es liefert auch true für '06', also. Wählen Sie Ihr Gift, denke ich.
str.isdigit()
sollte das genügen.
Beispiele:
str.isdigit("23") ## True
str.isdigit("abc") ## False
str.isdigit("23.4") ## False
EDIT : Wie @BuzzMoschetti feststellte, wird dieser Weg bei Minuszahl (z.B., "-23" ). Für den Fall, dass Ihr Eingabe_Zahl kleiner als 0 sein kann, verwenden Sie re.sub(regex_search,regex_replace,contents) vor der Anwendung str.isdigit() . Zum Beispiel:
import re
input_num = "-23"
input_num = re.sub("^-", "", input_num) ## "^" indicates to remove the first "-" only
str.isdigit(input_num) ## True
Verwenden Sie einen regulären Ausdruck:
import re
def RepresentsInt(s):
return re.match(r"[-+]?\d+$", s) is not None
Wenn Sie auch Dezimalbrüche akzeptieren müssen:
def RepresentsInt(s):
return re.match(r"[-+]?\d+(\.0*)?$", s) is not None
Um die Leistung zu verbessern, wenn Sie dies häufig tun, kompilieren Sie den regulären Ausdruck nur einmal mit re.compile()
.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
28 Stimmen
Warum versuchen beide, dies "auf die harte Tour" zu tun? Was ist falsch an try/except?
8 Stimmen
Ja, was ist falsch an try/except? Es ist besser, um Vergebung zu bitten als um Erlaubnis.
82 Stimmen
Ich würde fragen, warum sollte diese einfache Sache try/except erfordern? Das Ausnahmesystem ist ein komplexes Biest, aber dies ist ein einfaches Problem.
19 Stimmen
@Aivar hör auf, FUD zu verbreiten. Ein einzelner try/except-Block ist nicht einmal annähernd "komplex".
68 Stimmen
Es ist aber nicht wirklich FUD. Sie würden effektiv schreiben 4 Zeilen Code, erwarten, dass etwas zu explodieren, fangen, dass Ausnahme und tun Ihre Standard, anstatt mit einem Einzeiler.
2 Stimmen
Isinstance(deine_variable, basestring) sagt dir, ob die Variable entweder str oder unicode ist, oder beides. Dies beantwortet zwar nicht die spezifische Frage oben (mit der Umwandlung von String in eine Zahl), aber es beantwortet mindestens eine Frage, die als Duplikat zu dieser auf einer anderen Seite markiert ist, oder zumindest die Frage, die ich hatte, als ich diese Seite fand.
0 Stimmen
Hausaufgaben verbieten manchmal die Verwendung von try:. Wenn eine Ausnahme auftritt, selbst wenn Sie sie behandeln, wird sie erkannt und Sie bestehen die Aufgabe nicht.
4 Stimmen
@johnktejik Hier ist eine Idee - erstellen Sie einen Webservice, der die Frage beantwortet, ob eine Zeichenkette eine ganze Zahl sein kann, und stellen Sie dann im Code Ihrer Aufgabe eine HTTP-Anfrage an ihn. Der Webservice kann das try/catch ausführen
3 Stimmen
@dagrooms Ich liebe es. Ich frage mich, ob ihr Hacker-Alarm losgehen würde.
1 Stimmen
@S.Lott ich versuche dies in einem Listenverständnis zu tun also kein Versuch außer
2 Stimmen
Ausnahmen sind in Python üblich. Man kann nicht einmal eine
for
Schleife ohne Ausnahmebehandlung - einefor
Schleife stoppt, wenn der Iterator einStopIteration
Ausnahme. Die Website Entwurfsabsicht ist, dass Sie, wenn Sie wissen wollen, ob eine Zeichenkette als Ganzzahl interpretiert werden kann, die Funktionint
und fangen die Ausnahme ab.5 Stimmen
"Mach es auf die pythonische Art!", "Mach es auf die Microsoft-Art!", "Mach es auf die Google-Art!", "Mach es auf meine Art!". Wie wäre es mit Der Auftraggeber hat eine Frage gestellt, wie man etwas macht und die Bedingungen dafür genannt. Ich habe ein ähnliches Problem: Ich versuche herauszufinden, wie ich ein Element in einer Liste überprüfen kann, und die Übung sagt ausdrücklich, dass ich try/except nicht verwenden kann, und einige andere Einschränkungen, einschließlich einiger Einschränkungen hinsichtlich Leistung und Optimierung. Bis jetzt habe ich noch keine Lösung für diese Aufgabe gefunden.
2 Stimmen
@S.Lott Wenn Ausnahmen nicht außergewöhnlich sind, warum werden sie dann Ausnahmen genannt? Ausnahmen sollten für die Behandlung von Fehlern (und ich meine Fehler: Programmierfehler) sein. Ausnahmen sind der einzige Teil von Python, den ich nicht mag.
0 Stimmen
Ich denke, dass die Tatsache, dass OP nicht genau definiert, was ob eine Zeichenkette eine ganze Zahl darstellt hat zu einem Haufen unnötiger Verwirrung und Streitereien geführt.
1 Stimmen
Warum nicht try/except verwenden? Weil man sie nicht in einer Lambda-Funktion verwenden kann, wie man sie z.B. in
filter()
. Natürlich ist die Definition einer Nicht-Lambda-Funktion immer kurz und klar, so dass es keine große Sache ist, aber es ist gültig Frage.0 Stimmen
Was ist der Unterschied zu
s.isnumeric()
?