Wie überprüfe ich, ob die Zeichenfolge leer ist?

1419

Hat Python so etwas wie eine leere Zeichenfolgenvariable, in der Sie Folgendes tun können:

if myString == string.empty:

Was ist die eleganteste Methode, um nach leeren Zeichenfolgenwerten zu suchen? Ich finde harte Codierung ""jedes Mal für das Überprüfen einer leeren Zeichenfolge nicht so gut.

Joan Venge
quelle
2
Wie ist ""nicht so gut?
NoName

Antworten:

2117

Leere Zeichenfolgen sind "falsch", was bedeutet, dass sie in einem booleschen Kontext als falsch betrachtet werden. Sie können also einfach Folgendes tun:

if not myString:

Dies ist der bevorzugte Weg, wenn Sie wissen, dass Ihre Variable eine Zeichenfolge ist. Wenn Ihre Variable auch ein anderer Typ sein könnte, sollten Sie verwenden myString == "". Weitere Werte, die in booleschen Kontexten falsch sind, finden Sie in der Dokumentation zum Testen von Wahrheitswerten .

Andrew Clark
quelle
183
Seien Sie vorsichtig, da viele andere Dinge ebenfalls falsch sind.
Ignacio Vazquez-Abrams
9
Ich habe noch nie von dem Begriff Falschheit gehört. Bedeutet das, dass es falsch zurückgibt?
Joan Venge
41
@Joan: Wird in einem booleschen Kontext als falsch ausgewertet.
Ignacio Vazquez-Abrams
54
OP will wissen , ob die Variable eine leere Zeichenfolge ist, aber sie würde auch die Eingabe - if not myString:Blocks , wenn myStringwaren None, 0, Falseusw. Also , wenn Sie sicher sind , nicht das, was Typ myStringist, sollten Sie if myString == "":bestimmen, ob es eine leere Zeichenfolge ist im Gegensatz zu ein anderer falscher Wert.
Andrew Clark
15
@ AndrewClark, für einen solchen Fall if myString == ...könnten wir anstelle einer Kette von Ausdrücken if myString in (None, '')oder per @Bartek,if myString in (None, '') or not myString.strip()
Stew
414

Ab PEP 8 im Abschnitt „Programmierempfehlungen“ :

Verwenden Sie für Sequenzen (Zeichenfolgen, Listen, Tupel) die Tatsache, dass leere Sequenzen falsch sind.

Sie sollten also Folgendes verwenden:

if not some_string:

oder:

if some_string:

Zur Verdeutlichung werden Sequenzen in oder in einem Booleschen Kontext ausgewertet , ob sie leer sind oder nicht. Sie sind nicht gleich zu oder .FalseTrueFalseTrue

Zenpoy
quelle
24
Schön, dass Sie Verweise auf das PEP aufgenommen haben!
Felix
3
PS: Zur Verteidigung der PEP könnte man argumentieren, dass " x ist falsch " (Kleinbuchstaben falsch ) dies bereits bedeutet und nicht bedeutet x == False. Aber meiner Meinung nach ist die Klarstellung angesichts der Zielgruppe immer noch willkommen.
MestreLion
234

Der eleganteste Weg wäre wahrscheinlich, einfach zu überprüfen, ob es wahr oder falsch ist, z.

if not my_string:

Möglicherweise möchten Sie jedoch Leerzeichen entfernen, weil:

 >>> bool("")
 False
 >>> bool("   ")
 True
 >>> bool("   ".strip())
 False

Sie sollten diesbezüglich jedoch wahrscheinlich etwas expliziter sein, es sei denn, Sie wissen sicher, dass diese Zeichenfolge eine Validierung bestanden hat und auf diese Weise getestet werden kann.

Bartek
quelle
88

Ich würde die Einheit vor dem Strippen testen. Außerdem würde ich die Tatsache verwenden, dass leere Zeichenfolgen False (oder Falsy) sind. Dieser Ansatz ähnelt Apaches StringUtils.isBlank oder Guavas Strings.isNullOrEmpty

Dies ist, was ich verwenden würde, um zu testen, ob eine Zeichenfolge entweder Keine ODER Leer ODER Leer ist:

def isBlank (myString):
    if myString and myString.strip():
        #myString is not None AND myString is not empty or blank
        return False
    #myString is None OR myString is empty or blank
    return True

Und das genaue Gegenteil, um zu testen, ob eine Zeichenfolge nicht None NOR Empty NOR Blank ist:

def isNotBlank (myString):
    if myString and myString.strip():
        #myString is not None AND myString is not empty or blank
        return True
    #myString is None OR myString is empty or blank
    return False

Prägnantere Formen des obigen Codes:

def isBlank (myString):
    return not (myString and myString.strip())

def isNotBlank (myString):
    return bool(myString and myString.strip())
Rubel
quelle
warum nicht if mystring and not mystring.strip()?
Migol
1
Wie unterscheidet es sich von string and not string.isspace()?
Andrea Corbellini
7
Prägnanter für diejenigen, die sich für solche Dinge interessieren: def isBlank(s): return not (s and s.strip())und def isNotBlank(s): return s and s.strip().
Carl
49

Ich habe einmal etwas Ähnliches wie Barteks Antwort geschrieben und Javascript inspiriert:

def is_not_blank(s):
    return bool(s and s.strip())

Prüfung:

print is_not_blank("")    # False
print is_not_blank("   ") # False
print is_not_blank("ok")  # True
print is_not_blank(None)  # False
Gewölbe
quelle
Warum nicht einfachreturn bool(s.strip())
anilbey
1
AttributeError: 'NoneType' object has no attribute 'strip'
Gewölbe
28

Der einzig wirklich solide Weg, dies zu tun, ist der folgende:

if "".__eq__(myString):

Alle anderen Lösungen haben mögliche Probleme und Randfälle, in denen die Prüfung fehlschlagen kann.

len(myString)==0kann fehlschlagen, wenn myStringes sich um ein Objekt einer Klasse handelt, die von strder __len__()Methode erbt und diese überschreibt .

Ebenso myString == ""und myString.__eq__("")kann fehlschlagen, wenn und myStringüberschrieben .__eq__()__ne__()

Aus irgendeinem Grund wird "" == myStringauch getäuscht, wenn myStringüberschreibt __eq__().

myString is ""und "" is myStringsind gleichwertig. Sie schlagen beide fehl, wenn myStringes sich nicht um eine Zeichenfolge, sondern um eine Unterklasse von Zeichenfolgen handelt (beide werden zurückgegeben False). Da es sich um Identitätsprüfungen handelt, ist der einzige Grund, warum sie funktionieren, dass Python String Pooling (auch als String Internment bezeichnet) verwendet, das dieselbe Instanz eines Strings verwendet, wenn dieser interniert ist (siehe hier: Warum werden Strings mit entweder '= verglichen? = 'oder' ist 'manchmal ein anderes Ergebnis erzeugen? ). Und ""ist von Anfang an in CPython interniert

Das große Problem bei der Identitätsprüfung ist, dass die String-Internierung (soweit ich feststellen konnte) nicht standardisiert ist, welche Strings interniert werden. Das heißt, theoretisch ""ist intern nicht notwendig und das ist implementierungsabhängig.

Der einzige Weg, der wirklich nicht getäuscht werden kann, ist der eingangs erwähnte : "".__eq__(myString). Da dies die __eq__()Methode der leeren Zeichenfolge explizit aufruft , kann sie nicht durch Überschreiben von Methoden in myString getäuscht werden und funktioniert solide mit Unterklassen von str.

Auch das Verlassen auf die Falschheit einer Zeichenfolge funktioniert möglicherweise nicht, wenn das Objekt seine __bool__()Methode überschreibt .

Dies ist nicht nur eine theoretische Arbeit, sondern könnte auch für den realen Gebrauch relevant sein, da ich zuvor Frameworks und Bibliotheken gesehen habe, deren Unterklassen strund deren Verwendung dort myString is ""möglicherweise eine falsche Ausgabe zurückgeben.

Außerdem ist das Vergleichen von Strings isim Allgemeinen eine ziemlich böse Falle, da es manchmal richtig funktioniert, aber nicht zu anderen Zeiten, da das Pooling von Strings ziemlich seltsamen Regeln folgt.

In den meisten Fällen funktionieren jedoch alle genannten Lösungen ordnungsgemäß. Dies ist Post ist meist akademische Arbeit.

Dakkaron
quelle
2
@simpleuser du hast natürlich recht. In der realen Welt ist es völlig in Ordnung, die Falschheit der Zeichenfolge zu verwenden oder sie mit einer leeren Zeichenfolge zu vergleichen. Diese Antwort hier ist absichtlich übertrieben.
Dakkaron
Verwenden Sie wirklich eq_ ?
Slboat
Arbeit super, danke!
eugene.polschikov
14

Leere oder leere Zeichenfolge testen (kürzerer Weg):

if myString.strip():
    print("it's not an empty or blank string")
else:
    print("it's an empty or blank string")
prrvchr
quelle
7
Wenn myString = None, wird eine Ausnahme ausgelöst. Verwenden Sie besser die Antwort von
Dominik
9

Wenn Sie zwischen leeren und Null-Zeichenfolgen unterscheiden möchten, würde ich die Verwendung vorschlagen if len(string), andernfalls würde ich die Verwendung einfach if stringso vorschlagen, wie andere gesagt haben. Die Einschränkung bezüglich Zeichenfolgen voller Leerzeichen gilt jedoch weiterhin. Vergessen Sie es also nicht strip.

Silas Ray
quelle
Ich weiß nicht, warum Sie die Verwendung von "" vermeiden möchten, es sei denn, dies wirkt sich irgendwie auf die Leistung aus, aber ich ziehe Ihre Antwort der Antwort mit zig Millionen von positiven Stimmen vor, da sie weniger verwirrend ist. Ich wollte jedoch darauf hinweisen, dass eine leere Liste anscheinend auch falsch ist.
Brōtsyorfuzthrāx
7

if stringname:gibt ein, falsewenn die Zeichenfolge leer ist. Einfacher geht es wohl nicht.

Kakashi
quelle
6
a = ''
b = '   '
a.isspace() -> False
b.isspace() -> True
Roman Semirook
quelle
1
Verstehe wirklich nicht, was diese Lösung bringt. Bei der Frage geht es darum zu testen, ob eine Zeichenfolge leer ist. Wenn Sie festlegen a='a', würden Sie erhalten a.isspace() -> False, aber anicht auf diesem Konto wäre eine leere Zeichenfolge.
Adrian Keister
6

Ich finde Hardcoding (sic) jedes Mal, wenn ich eine leere Zeichenfolge überprüfe, nicht so gut.

Clean Code-Ansatz

Dies zu tun: foo == ""ist eine sehr schlechte Praxis. ""ist ein magischer Wert. Sie sollten niemals gegen magische Werte prüfen (besser bekannt als magische Zahlen ).

Was Sie tun sollten, ist mit einem beschreibenden Variablennamen zu vergleichen.

Beschreibende Variablennamen

Man könnte denken, dass "empty_string" ein beschreibender Variablenname ist. Ist es nicht .

Bevor Sie loslegen und empty_string = ""denken, Sie hätten einen großartigen Variablennamen, mit dem Sie vergleichen können. Dies ist nicht das, was "beschreibender Variablenname" bedeutet.

Ein guter beschreibender Variablenname basiert auf seinem Kontext. Sie müssen darüber nachdenken, was die leere Zeichenfolge ist .

  • Woher kommt das.
  • Warum ist es dort?
  • Warum müssen Sie danach suchen?

Einfaches Beispiel für ein Formularfeld

Sie erstellen ein Formular, in das ein Benutzer Werte eingeben kann. Sie möchten überprüfen, ob der Benutzer etwas geschrieben hat oder nicht.

Ein guter Variablenname kann sein not_filled_in

Dies macht den Code sehr lesbar

if formfields.name == not_filled_in:
    raise ValueError("We need your name")

Beispiel für eine gründliche CSV-Analyse

Sie analysieren CSV-Dateien und möchten, dass die leere Zeichenfolge als analysiert wird None

(Da CSV vollständig textbasiert ist, kann es nicht darstellen None ohne Verwendung vordefinierter Schlüsselwörter dargestellt werden.)

Ein guter Variablenname kann sein CSV_NONE

Dies erleichtert das Ändern und Anpassen des Codes, wenn Sie eine neue CSV-Datei haben, die Nonemit einer anderen Zeichenfolge als dargestellt wird""

if csvfield == CSV_NONE:
    csvfield = None

Es gibt keine Fragen darüber, ob dieser Code korrekt ist. Es ist ziemlich klar, dass es tut, was es tun sollte.

Vergleichen Sie dies mit

if csvfield == EMPTY_STRING:
    csvfield = None

Die erste Frage lautet hier: Warum verdient die leere Zeichenfolge eine besondere Behandlung?

Dies würde zukünftigen Codierern mitteilen, dass eine leere Zeichenfolge immer als betrachtet werden sollte None.

Dies liegt daran, dass Geschäftslogik (welcher CSV-Wert sein sollte None) mit Codeimplementierung gemischt wird (womit vergleichen wir eigentlich)

Es muss eine Trennung der Bedenken zwischen den beiden geben.

Firelynx
quelle
1
Muss man sich wirklich so viel Mühe geben, um ein "" zu vermeiden? Was könnte eine leere Zeichenfolge im Vergleich noch bedeuten?
Während ich in meine Antwort schreibe, kann CSV ohne Verwendung einer Zeichenfolge nicht null darstellen. Wenn Sie kontextfrei sind, dann herzlichen Glückwunsch! Der meiste Code ist nicht.
Firelynx
2
Sie sagen, "not_filled_in" ist aussagekräftiger als "empty_string"? Ich sage du bist hoch.
Tuncay Göncüoğlu
@ TuncayGöncüoğlu "Leere Zeichenfolge" beschreibt nicht, worauf die if-Anweisung testet.
Firelynx
5
Ich würde dieser Antwort nicht zustimmen. Magische Zahlen sind schlecht, das macht Sinn. Magische Werte im Allgemeinen auch. Aber ""ist kein Zauber Wert, gleich wie True, Falseoder Nonesind nicht magische Werte.
Dakkaron
5

Wie wäre es damit? Vielleicht ist es nicht "das eleganteste", aber es scheint ziemlich vollständig und klar zu sein:

if (s is None) or (str(s).strip()==""): // STRING s IS "EMPTY"...
BuvinJ
quelle
In den meisten Fällen ist eine Zeichenfolge mit Leerzeichen nicht "leer".
Chris Johnson
Ich nehme an, Sie meinen nichts als Leerraum? Sie beziehen sich auf meine Verwendung von strip ()? Für die meisten Zwecke ist das leer! Es ist lächerlich üblich, etwas wie s.trim () zusammenzusetzen. IsEmpty ()
BuvinJ
Hey @ Chris Johnson, hast du gesehen, dass die meisten Antworten hier auch strip () verwenden? Haben Sie uns alle oder nur mich abgelehnt?
BuvinJ
4

Antwort auf @ 1290. Es gibt leider keine Möglichkeit, Blöcke in Kommentaren zu formatieren. Der NoneWert ist in Python keine leere Zeichenfolge und (Leerzeichen) auch nicht. Die Antwort von Andrew Clark ist die richtige : if not myString. Die Antwort von @rouble ist anwendungsspezifisch und beantwortet die Frage des OP nicht. Sie werden in Schwierigkeiten geraten, wenn Sie eine eigenartige Definition einer "leeren" Zeichenfolge übernehmen. Insbesondere ist das Standardverhalten, das str(None)erzeugt'None' , eine nicht leere Zeichenfolge.

Wenn Sie jedoch Noneund (Leerzeichen) als "leere" Zeichenfolgen behandeln müssen, ist dies ein besserer Weg:

class weirdstr(str):
    def __new__(cls, content):
        return str.__new__(cls, content if content is not None else '')
    def __nonzero__(self):
        return bool(self.strip())

Beispiele:

>>> normal = weirdstr('word')
>>> print normal, bool(normal)
word True

>>> spaces = weirdstr('   ')
>>> print spaces, bool(spaces)
    False

>>> blank = weirdstr('')
>>> print blank, bool(blank)
 False

>>> none = weirdstr(None)
>>> print none, bool(none)
 False

>>> if not spaces:
...     print 'This is a so-called blank string'
... 
This is a so-called blank string

Erfüllt die @ problem-Anforderungen, ohne das erwartete boolVerhalten von Zeichenfolgen zu beeinträchtigen .

Chris Johnson
quelle
python -c "if (str(None) == 'None'): print ('OMG, WHY ??')"
Yordan Georgiev
3

Ich finde das elegant, da es sicherstellt, dass es sich um eine Zeichenfolge handelt und deren Länge überprüft:

def empty(mystring):
    assert isinstance(mystring, str)
    if len(mystring) == 0:
        return True
    else:
        return False
Kardamom
quelle
Warnung: Asserts sind als Debugging-Tool gedacht und werden optimiert, wenn Sie das -OFlag PYTHONOPTIMIZEdrücken oder die env-Variable setzen.
SilentVoid
2

Eine andere einfache Möglichkeit könnte darin bestehen, eine einfache Funktion zu definieren:

def isStringEmpty(inputString):
    if len(inputString) == 0:
        return True
    else:
        return False
tanzil
quelle
3
Die Antwort von Kardamom ist vollständiger, wenn wir überprüfen möchten, ob die Eingabe eine Zeichenfolge ist oder nicht
tanzil
1
not str(myString)

Dieser Ausdruck gilt für leere Zeichenfolgen. Nicht leere Zeichenfolgen, Keine und Nicht-Zeichenfolgen-Objekte erzeugen alle False, mit der Einschränkung, dass Objekte __str__ überschreiben können, um diese Logik durch Rückgabe eines falschen Werts zu vereiteln.

Fax
quelle
0

Wenn Sie eine Datei zeilenweise lesen und feststellen möchten, welche Zeile leer ist, stellen Sie sicher, dass Sie sie verwenden .strip(), da die "leere" Zeile ein neues Zeilenzeichen enthält:

lines = open("my_file.log", "r").readlines()

for line in lines:
    if not line.strip():
        continue

    # your code for non-empty lines
Pavel Štěrba
quelle
0
str = ""
if not str:
   print "Empty String"
if(len(str)==0):
   print "Empty String"
Tanmoy Datta
quelle
0

Wenn Sie nur verwenden

not var1 

Es ist nicht möglich, eine boolesche Variable Falsevon einer leeren Zeichenfolge zu unterscheiden '':

var1 = ''
not var1
> True

var1 = False
not var1
> True

Wenn Sie Ihrem Skript jedoch eine einfache Bedingung hinzufügen, wird der Unterschied gemacht:

var1  = False
not var1 and var1 != ''
> True

var1 = ''
not var1 and var1 != ''
> False
jberrio
quelle
0

Für den Fall, dass dies für jemanden nützlich ist, ist hier eine schnelle Funktion, die ich entwickelt habe, um leere Zeichenfolgen durch N / A in Listen von Listen zu ersetzen (Python 2).

y = [["1","2",""],["1","4",""]]

def replace_blank_strings_in_lists_of_lists(list_of_lists):
    new_list = []
    for one_list in list_of_lists:
        new_one_list = []
        for element in one_list:
            if element:
                new_one_list.append(element)
            else:
                new_one_list.append("N/A")
        new_list.append(new_one_list)
    return new_list


x= replace_blank_strings_in_lists_of_lists(y)
print x

Dies ist nützlich, um Listen mit Listen in einer MySQL-Datenbank zu veröffentlichen, die für bestimmte Felder keine Leerzeichen akzeptiert (Felder, die im Schema als NN markiert sind. In meinem Fall war dies auf einen zusammengesetzten Primärschlüssel zurückzuführen).

FlyingZebra1
quelle
-1

Ich habe mit Zeichenfolgen wie '', '', '\ n' usw. experimentiert. Ich möchte, dass isNotWhitespace genau dann True ist, wenn die Variable foo eine Zeichenfolge mit mindestens einem Nicht-Leerzeichen ist. Ich benutze Python 3.6. Folgendes habe ich erreicht:

isWhitespace = str is type(foo) and not foo.strip()
isNotWhitespace = str is type(foo) and not not foo.strip()

Wickeln Sie dies bei Bedarf in eine Methodendefinition ein.

Tom Stambaugh
quelle
-3

Wie oben angegeben, aber mit Fehler.

def isNoneOrEmptyOrBlankString (myString):
    if myString:
        if not myString.strip():
            return True
        else:
            return False
    return False
Schatten
quelle
Gerade getestet: Sein Code gibt True für ""und " "und False für zurück "a"(genau wie erwartet). Ihr Code gibt dasselbe zurück, mit Ausnahme der leeren Zeichenfolge, die True zurückgibt, was nicht der Fall sein sollte.
AbcAeffchen
sry zu müde: Ihr Code gibt False für die leere Zeichenfolge zurück.
AbcAeffchen
Dieser Code ist falsch. Sie geben False zurück, wenn eine Zeichenfolge leer oder keine ist.
Rubel