Hoe controleer ik of de string leeg is?

Heeft Python zoiets als een lege tekenreeksvariabele waar je het volgende kunt doen:

if myString == string.empty:

Hoe dan ook, wat is de meest elegante manier om te controleren op lege tekenreekswaarden? Ik vind harde codering "" elke keer voor het controleren van een lege string niet zo goed.


Antwoord 1, autoriteit 100%

Lege strings zijn “falsy” (python 2 of python 3 referentie), wat betekent dat ze als onwaar worden beschouwd in een Booleaanse context, dus u kan gewoon dit:

if not myString:

Dit is de beste manier als je weet dat je variabele een string is. Als uw variabele ook van een ander type kan zijn, moet u myString == "" gebruiken. Zie de documentatie over Truth Value Testing voor andere waarden die onwaar zijn in Booleaanse contexten.


Antwoord 2, autoriteit 19%

Van PEP 8, in de Programmeeraanbevelingen sectie:

Gebruik voor reeksen (strings, lijsten, tuples) het feit dat lege reeksen onwaar zijn.

Dus je moet gebruiken:

if not some_string:

of:

if some_string:

Voor alle duidelijkheid: reeksen worden geëvalueerd tot False of True in een Booleaanse context, of ze nu leeg zijn of niet. Ze zijn niet gelijk aan False of True.


Antwoord 3, autoriteit 11%

De meest elegante manier zou waarschijnlijk zijn om gewoon te controleren of het waar of niet waar is, bijvoorbeeld:

if not my_string:

Het is echter mogelijk dat u witruimte wilt verwijderen omdat:

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

Je zou hier waarschijnlijk wat explicieter in moeten zijn, tenzij je zeker weet dat deze string een soort van validatie heeft doorstaan ​​en een string is die op deze manier kan worden getest.


Antwoord 4, autoriteit 4%

Ik zou nietigheid testen voordat ik ga strippen. Ik zou ook het feit gebruiken dat lege strings False (of Falsy) zijn. Deze aanpak is vergelijkbaar met Apache’s StringUtils.isBlank of Guava’s Strings.isNullOrEmpty

Dit is wat ik zou gebruiken om te testen of een tekenreeks Geen OF Leeg OF Leeg is:

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

En precies het tegenovergestelde om te testen of een string niet Geen NOR Leeg NOR Leeg is:

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

Meer beknopte vormen van de bovenstaande code:

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

Antwoord 5, autoriteit 3%

Ik heb ooit iets geschreven dat lijkt op het antwoord van Bartek en geïnspireerd door javascript:

def is_not_blank(s):
    return bool(s and not s.isspace())

Testen:

print is_not_blank("")    # False
print is_not_blank("   ") # False
print is_not_blank("ok")  # True
print is_not_blank(None)  # False

Antwoord 6, autoriteit 2%

De enige echt solide manier om dit te doen is de volgende:

if "".__eq__(myString):

Alle andere oplossingen hebben mogelijke problemen en randgevallen waarbij de controle kan mislukken.

len(myString)==0 kan mislukken als myString een object is van een klasse die erft van str en de __len__() methode.

Evenzo kunnen myString == "" en myString.__eq__("") mislukken als myString __eq__() en __ne__().

Om de een of andere reden wordt "" == myString ook voor de gek gehouden als myString __eq__() overschrijft.

myString is "" en "" is myString zijn equivalent. Ze zullen allebei mislukken als myString eigenlijk geen string is maar een subklasse van string (beide zullen False retourneren). Omdat het identiteitscontroles zijn, is de enige reden waarom ze werken, ook omdat Python String Pooling gebruikt (ook wel String Internment genoemd) die dezelfde instantie van een string gebruikt als deze is geïnterneerd (zie hier: Waarom levert het vergelijken van strings met behulp van ‘==’ of ‘is’ soms een ander resultaat?). En "" is vanaf het begin geïnterneerd in CPython

Het grote probleem met de identiteitscontrole is dat String Internment (voor zover ik kon vinden) is dat niet gestandaardiseerd is welke strings worden geïnterneerd. Dat betekent dat in theorie "" niet noodzakelijk geïnterneerd hoeft te worden en dat is implementatie-afhankelijk.

De enige manier om dit te doen die echt niet voor de gek gehouden kan worden, is degene die in het begin wordt genoemd: "".__eq__(myString). Aangezien dit expliciet de methode __eq__() van de lege string aanroept, kan het niet voor de gek gehouden worden door methoden in myString te overschrijven en werkt het solide met subklassen van str.

Ook vertrouwen op de onjuistheid van een tekenreeks werkt mogelijk niet als het object de methode __bool__() overschrijft.

Dit is niet alleen theoretisch werk, maar kan ook relevant zijn in het echte gebruik, aangezien ik eerder frameworks en bibliotheken heb gezien die str subclasseren en het gebruik van myString is "" zou een verkeerde uitvoer daar.

Bovendien is het vergelijken van strings met behulp van is in het algemeen een behoorlijk slechte valstrik omdat het soms correct zal werken, maar andere keren niet, omdat string pooling vrij vreemde regels volgt.

Dat gezegd hebbende, zullen in de meeste gevallen alle genoemde oplossingen correct werken. Dit is een bericht dat voornamelijk academisch werk is.


Antwoord 7

Test lege of lege string (kortere weg):

if myString.strip():
    print("it's not an empty or blank string")
else:
    print("it's an empty or blank string")

Antwoord 8

Als je onderscheid wilt maken tussen lege en null-tekenreeksen, raad ik aan om if len(string) te gebruiken, anders raad ik je aan om gewoon if string te gebruiken zoals andere hebben gezegd. Het voorbehoud over strings vol witruimte is echter nog steeds van toepassing, dus vergeet niet te strip.


Antwoord 9

if stringname: geeft een False als de string leeg is. Ik denk dat het niet eenvoudiger kan dan dit.


Antwoord 10

Ik vind hardcoding(sic) "" elke keer voor het controleren van een lege string die niet zo goed is.

Aanpak voor schone code

Dit doen: foo == "" is een zeer slechte gewoonte. "" is een magische waarde. Je moet nooit toetsen aan magische waarden (beter bekend als magische getallen)

Wat u moet doen, is vergelijken met een beschrijvende variabelenaam.

Beschrijvende namen van variabelen

Je zou kunnen denken dat "empty_string" is een beschrijvende variabelenaam. Dat is het niet.

Voordat je empty_string = "" doet en denkt dat je een geweldige variabelenaam hebt om mee te vergelijken. Dit is niet wat "beschrijvende variabelenaam" betekent.

Een goede beschrijvende variabelenaam is gebaseerd op zijn context.
Je moet nadenken over wat de lege string is.

  • Waar komt het vandaan.
  • Waarom is het daar.
  • Waarom moet je ernaar kijken.

Eenvoudig formulierveldvoorbeeld

U bouwt een formulier waarin een gebruiker waarden kan invoeren. U wilt controleren of de gebruiker iets heeft geschreven of niet.

Een goede variabelenaam kan not_filled_in

zijn

Dit maakt de code zeer leesbaar

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

Uitgebreide CSV-parseervoorbeeld

U bent CSV-bestanden aan het parseren en wilt dat de lege tekenreeks wordt geparseerd als None

(Aangezien CSV volledig op tekst is gebaseerd, kan het niet None vertegenwoordigen zonder vooraf gedefinieerde trefwoorden te gebruiken)

Een goede variabelenaam kan CSV_NONE

zijn

Dit maakt het gemakkelijk om de code te wijzigen en aan te passen als u een nieuw CSV-bestand heeft dat None vertegenwoordigt met een andere tekenreeks dan ""

if csvfield == CSV_NONE:
    csvfield = None

Er zijn geen vragen of dit stukje code correct is. Het is vrij duidelijk dat het doet wat het moet doen.

Vergelijk dit met

if csvfield == EMPTY_STRING:
    csvfield = None

De eerste vraag hier is: Waarom verdient de lege string een speciale behandeling?

Dit zou toekomstige programmeurs vertellen dat een lege tekenreeks altijd als None moet worden beschouwd.

Dit komt omdat het bedrijfslogica (welke CSV-waarde None moet zijn) combineert met code-implementatie (waarmee vergelijken we eigenlijk)

Er moet een scheiding van zorg tussen beide zijn.


Antwoord 11

a = ''
b = '   '
a.isspace() -> False
b.isspace() -> True

Antwoord 12

Hoe zit het hiermee? Misschien niet “de meest elegante”, maar het lijkt vrij compleet en duidelijk:

if (s is None) or (str(s).strip()==""): // STRING s IS "EMPTY"...

Antwoord 13

Reageren op @1290. Sorry, geen manier om blokken in opmerkingen op te maken. De waarde None is geen lege tekenreeks in Python, en dat is ook niet (spaties). Het antwoord van Andrew Clark is het juiste: if not myString. Het antwoord van @rouble is toepassingsspecifiek en geeft geen antwoord op de vraag van de OP. U komt in de problemen als u een eigenaardige definitie aanneemt van wat een “lege” string is. In het bijzonder is het standaardgedrag dat str(None) 'None' produceert, een niet-lege string.

Als u echter None en (spaties) als “lege” tekenreeksen moet behandelen, is dit een betere manier:

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())

Voorbeelden:

>>> 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

Voldoet aan de @rouble-vereisten zonder het verwachte bool-gedrag van strings te doorbreken.


Antwoord 14

Ik heb wat geëxperimenteerd met strings zoals ”, ‘ ‘, ‘\n’, etc. Ik wil dat isNotWhitespace True is als en alleen als de variabele foo een string is met ten minste één niet-witruimte-teken. Ik gebruik Python 3.6. Dit is waar ik mee eindigde:

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

Verpak dit desgewenst in een methodedefinitie.


Antwoord 15

not str(myString)

Deze expressie is True voor strings die leeg zijn. Niet-lege strings, None en non-string objecten zullen allemaal False produceren, met het voorbehoud dat objecten __str__ kunnen overschrijven om deze logica te dwarsbomen door een false waarde te retourneren.


Antwoord 16

Misschien kun je deze Lege waarde toewijzen of tekenreeks in Python

Dit gaat over het vergelijken van strings die leeg zijn. Dus in plaats van te testen op leegte met not, kun je testen of je string gelijk is aan een lege string met "" de lege string…


Antwoord 17

voor degenen die gedrag verwachten zoals de apache StringUtils.isBlank of Guava Strings.isNullOrEmpty :

if mystring and mystring.strip():
    print "not blank string"
else:
    print "blank string"

Antwoord 18

Als u het bestand per regel leest en wilt bepalen welke regel leeg is, zorg er dan voor dat u .strip() gebruikt, omdat er een nieuw regelteken in de “lege” regel staat:

lines = open("my_file.log", "r").readlines()
for line in lines:
    if not line.strip():
        continue
    # your code for non-empty lines

Antwoord 19

Als je gewoon

. gebruikt

not var1 

het is niet mogelijk om een ​​variabele die boolean False is te onderscheiden van een lege string '':

var1 = ''
not var1
> True
var1 = False
not var1
> True

Als u echter een eenvoudige voorwaarde aan uw script toevoegt, wordt het verschil gemaakt:

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

Antwoord 20

In het geval dat dit nuttig is voor iemand, hier is een snelle functie die ik heb gebouwd om lege strings te vervangen door N/A’s in lijsten met lijsten (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

Dit is handig voor het posten van lijsten met lijsten naar een mysql-database die geen spaties accepteert voor bepaalde velden (velden gemarkeerd als NN in het schema. in mijn geval was dit te wijten aan een samengestelde primaire sleutel).


Antwoord 21

Zoals prmatta hierboven gepost, maar ten onrechte.

def isNoneOrEmptyOrBlankString (myString):
    if myString:
        if not myString.strip():
            return True
        else:
            return False
    return False

LEAVE A REPLY

Please enter your comment!
Please enter your name here

6 − two =

Other episodes