Comment vérifier si la chaîne est vide?

1421

Python a-t-il quelque chose comme une variable de chaîne vide où vous pouvez faire:

if myString == string.empty:

Quoi qu'il en soit, quelle est la façon la plus élégante de vérifier les valeurs de chaîne vides? Je trouve que le codage dur à ""chaque fois pour vérifier une chaîne vide n'est pas aussi bon.

Joan Venge
la source
2
Comment est-ce ""pas aussi bon?
NoName

Réponses:

2117

Les chaînes vides sont "fausses", ce qui signifie qu'elles sont considérées comme fausses dans un contexte booléen, vous pouvez donc simplement faire ceci:

if not myString:

C'est le moyen préféré si vous savez que votre variable est une chaîne. Si votre variable peut également être d'un autre type, vous devez l'utiliser myString == "". Consultez la documentation sur le test de valeur de vérité pour d'autres valeurs fausses dans des contextes booléens.

Andrew Clark
la source
183
Soyez prudent, car beaucoup d'autres choses sont également fausses.
Ignacio Vazquez-Abrams
9
Je n'avais jamais entendu parler du terme de falsification auparavant. Cela signifie-t-il qu'il retourne faux?
Joan Venge
41
@Joan: Il est évalué comme faux dans un contexte booléen.
Ignacio Vazquez-Abrams
54
OP veut savoir si la variable est une chaîne vide, mais vous entrez aussi le if not myString:bloc si myStringétaient None, 0, Falseetc. Donc , si vous n'êtes pas sûr de quel type myStringest, vous devez utiliser if myString == "":pour déterminer si elle est une chaîne vide par opposition à une autre valeur falsifiée.
Andrew Clark
15
@AndrewClark, pour un tel cas, au lieu d'une chaîne d' if myString == ...expressions, nous pourrions utiliser if myString in (None, '')ou selon @Bartek,if myString in (None, '') or not myString.strip()
Stew
414

Depuis PEP 8 , dans la section «Recommandations de programmation» :

Pour les séquences (chaînes, listes, tuples), utilisez le fait que les séquences vides sont fausses.

Vous devez donc utiliser:

if not some_string:

ou:

if some_string:

Juste pour clarifier, les séquences sont évaluées vers Falseou Truedans un contexte booléen si elles sont vides ou non. Ils ne sont pas égaux à Falseou True.

Zenpoy
la source
24
Super que vous ayez inclus des références au PEP!
Felix
3
PS: Dans la défense du PEP, on pourrait soutenir que dire " x est faux " ( faux minuscule ) signifie déjà cela, plutôt que de signifier x == False. Mais à mon humble avis, la clarification est toujours la bienvenue étant donné le public cible.
MestreLion
234

La façon la plus élégante serait probablement de simplement vérifier si c'est vrai ou faux, par exemple:

if not my_string:

Cependant, vous souhaiterez peut-être supprimer les espaces blancs car:

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

Cependant, vous devriez probablement être un peu plus explicite à ce sujet, sauf si vous savez avec certitude que cette chaîne a passé une sorte de validation et est une chaîne qui peut être testée de cette façon.

Bartek
la source
88

Je testerais la nonité avant de me déshabiller. En outre, j'utiliserais le fait que les chaînes vides sont fausses (ou fausses). Cette approche est similaire à StringUtils.isBlank d' Apache ou à Strings.isNullOrEmpty de Guava

Voici ce que j'utiliserais pour tester si une chaîne est soit Aucune OU Vide OU Vide:

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

Et, exactement le contraire pour tester si une chaîne n'est pas None NOR Empty NOR Blank:

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

Formes plus concises du code ci-dessus:

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

def isNotBlank (myString):
    return bool(myString and myString.strip())
rouble
la source
pourquoi pas if mystring and not mystring.strip()?
Migol
1
En quoi est-il différent de string and not string.isspace()?
Andrea Corbellini
7
Plus concis pour ceux qui se soucient de telles choses: def isBlank(s): return not (s and s.strip())et def isNotBlank(s): return s and s.strip().
Carl
49

J'ai écrit une fois quelque chose de similaire à la réponse de Bartek et inspiré par javascript:

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

Tester:

print is_not_blank("")    # False
print is_not_blank("   ") # False
print is_not_blank("ok")  # True
print is_not_blank(None)  # False
voûte
la source
Pourquoi pasreturn bool(s.strip())
anilbey
1
AttributeError: 'NoneType' object has no attribute 'strip'
saut
29

La seule façon vraiment solide de procéder est la suivante:

if "".__eq__(myString):

Toutes les autres solutions ont des problèmes possibles et des cas limites où la vérification peut échouer.

len(myString)==0peut échouer si myStringest un objet d'une classe qui hérite de strla __len__()méthode et la remplace .

De même myString == ""et myString.__eq__("")peut échouer en cas de myStringsubstitution __eq__()et __ne__().

Pour une raison quelconque, "" == myStringil est également dupe en cas de myStringsubstitution __eq__().

myString is ""et "" is myStringsont équivalents. Ils échoueront tous les deux s'il myStringne s'agit pas réellement d'une chaîne mais d'une sous-classe de chaîne (les deux renverront False). De plus, comme il s'agit de contrôles d'identité, la seule raison pour laquelle ils fonctionnent est que Python utilise le regroupement de chaînes (également appelé internement de chaînes) qui utilise la même instance d'une chaîne si elle est internée (voir ici: Pourquoi comparer des chaînes en utilisant soit '= = 'ou' est 'produit parfois un résultat différent? ). Et ""est interné depuis le début dans CPython

Le gros problème avec le contrôle d'identité est que l'internement de chaînes est (pour autant que je puisse trouver) qu'il n'est pas standardisé quelles chaînes sont internées. Cela signifie, théoriquement, ""n'est pas nécessaire interné et cela dépend de la mise en œuvre.

La seule façon de faire ce qui ne peut vraiment pas être dupé est celui mentionné au début: "".__eq__(myString). Étant donné que cela appelle explicitement la __eq__()méthode de la chaîne vide, elle ne peut pas être dupe en remplaçant les méthodes dans myString et fonctionne solidement avec les sous-classes destr .

S'appuyer également sur la fausseté d'une chaîne peut ne pas fonctionner si l'objet remplace sa __bool__() méthode.

Ce n'est pas seulement un travail théorique, mais il pourrait en fait être pertinent dans l'utilisation réelle, car j'ai vu des cadres et des bibliothèques sous-classer stravant et utilisermyString is "" pourrait y retourner une sortie erronée.

De plus, comparer des chaînes en utilisant is en général est un piège assez mauvais car cela fonctionnera correctement parfois, mais pas à d'autres moments, car le regroupement de chaînes suit des règles assez étranges.

Cela dit, dans la plupart des cas, toutes les solutions mentionnées fonctionneront correctement. Ce poste est principalement un travail académique.

Dakkaron
la source
2
@simpleuser vous avez bien sûr raison. Dans le monde réel, il est tout à fait correct d'utiliser la fausseté de la chaîne ou de la comparer à une chaîne vide. Cette réponse ici est exagérée exprès.
Dakkaron
vraiment utiliser eq_ ?
slboat
travail génial, merci!
eugene.polschikov
14

Testez une chaîne vide ou vide (méthode plus courte):

if myString.strip():
    print("it's not an empty or blank string")
else:
    print("it's an empty or blank string")
prrvchr
la source
7
Si myString = None, cela lèvera une exception. Mieux vaut utiliser la réponse de
Dominik
9

Si vous voulez faire la différence entre des chaînes vides et nulles, je suggère d'utiliser if len(string), sinon, je suggère d'utiliser simplement if stringcomme d'autres l'ont dit. La mise en garde concernant les chaînes pleines d'espaces s'applique toujours, alors n'oubliez pas strip.

Silas Ray
la source
Je ne sais pas pourquoi vous voudriez éviter d'utiliser "", à moins que cela n'ait un impact sur les performances, mais je préfère votre réponse à celle avec des millions de votes positifs, car c'est moins déroutant. Cependant, je voulais souligner qu'une liste vide est également fausse, apparemment.
Brōtsyorfuzthrāx
7

if stringname:donne un falselorsque la chaîne est vide. Je suppose que cela ne peut pas être plus simple que cela.

Kakashi
la source
7

Je trouve que le "hardcoding (sic)" "à chaque fois pour vérifier une chaîne vide n'est pas aussi bon.

Approche de code propre

Faire ceci: foo == ""est une très mauvaise pratique. ""est une valeur magique. Vous ne devriez jamais vérifier les valeurs magiques (plus communément appelées nombres magiques )

Ce que vous devez faire, c'est comparer à un nom de variable descriptive.

Noms de variables descriptives

On peut penser que "empty_string" est un nom de variable descriptive. Ça ne l'est pas .

Avant de partir et empty_string = ""pensez que vous avez un excellent nom de variable à comparer. Ce n'est pas ce que signifie "nom de variable descriptive".

Un bon nom de variable descriptive est basé sur son contexte. Vous devez penser à ce que la chaîne vide est .

  • D'où est ce que ça vient.
  • Pourquoi est-il là?
  • Pourquoi avez-vous besoin de le vérifier?

Exemple de champ de formulaire simple

Vous créez un formulaire où un utilisateur peut entrer des valeurs. Vous voulez vérifier si l'utilisateur a écrit quelque chose ou non.

Un bon nom de variable peut être not_filled_in

Cela rend le code très lisible

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

Exemple d'analyse CSV approfondie

Vous analysez des fichiers CSV et souhaitez que la chaîne vide soit analysée comme None

(Étant donné que CSV est entièrement basé sur du texte, il ne peut pas représenter Nonesans utiliser de mots clés prédéfinis)

Un bon nom de variable peut être CSV_NONE

Cela rend le code facile à modifier et à adapter si vous avez un nouveau fichier CSV qui représente Noneavec une autre chaîne que""

if csvfield == CSV_NONE:
    csvfield = None

Il n'y a aucune question quant à savoir si ce morceau de code est correct. Il est assez clair qu'il fait ce qu'il devrait faire.

Comparez cela à

if csvfield == EMPTY_STRING:
    csvfield = None

La première question ici est: pourquoi la chaîne vide mérite-t-elle un traitement spécial?

Cela indiquerait aux futurs codeurs qu'une chaîne vide devrait toujours être considérée comme None.

En effet, il mélange la logique métier (quelle valeur CSV doit être None ) avec l'implémentation du code (à quoi est-ce que nous comparons réellement)

Il doit y avoir une séparation des préoccupations entre les deux.

firelynx
la source
1
Faut-il vraiment se donner beaucoup de mal pour éviter un ""? Dans le contexte de la comparaison, que pourrait signifier une chaîne vide?
Comme j'écris dans ma réponse, CSV ne peut pas représenter null sans utiliser une chaîne. Si vous êtes sans contexte, félicitations! La plupart des codes ne le sont pas.
firelynx
2
vous dites que "not_filled_in" est plus descriptif que "empty_string"? Je dis que tu es haut.
Tuncay Göncüoğlu
@ TuncayGöncüoğlu "Chaîne vide" ne décrit pas ce que l'instruction if teste.
firelynx
5
Je ne suis pas d'accord avec cette réponse. Les nombres magiques sont mauvais, c'est logique. Les valeurs magiques en général aussi. Mais ""n'est pas une valeur magique, même que True, Falseou Nonene sont pas des valeurs magiques.
Dakkaron
6
a = ''
b = '   '
a.isspace() -> False
b.isspace() -> True
Roman Semirook
la source
1
Je ne comprends vraiment pas ce que cette solution gagne. La question consiste à tester si une chaîne est vide. Si vous définissez, a='a'vous obtiendrez a.isspace() -> False, mais ane serait pas pour cette raison une chaîne vide.
Adrian Keister
5

Que dis-tu de ça? Ce n'est peut-être pas "le plus élégant", mais il semble assez complet et clair:

if (s is None) or (str(s).strip()==""): // STRING s IS "EMPTY"...
BuvinJ
la source
Dans la plupart des cas, une chaîne contenant des blancs n'est pas "vide".
Chris Johnson
Je suppose que tu ne veux dire que des espaces blancs? Vous faites référence à mon utilisation de strip ()? Pour la plupart des usages, c'est vide! Il est ridiculement courant de composer quelque chose comme s.trim (). IsEmpty ()
BuvinJ
Hé @Chris Johnson, avez-vous vu que la plupart des réponses ici utilisent également strip ()? Avez-vous voté contre nous tous, ou juste moi?
BuvinJ
4

Répondant à @ 1290. Désolé, aucun moyen de formater les blocs dans les commentaires. La Nonevaleur n'est pas une chaîne vide en Python, et ni l'un ni l'autre (espaces). La réponse d'Andrew Clark est le bon: if not myString. La réponse de @rouble est spécifique à l'application et ne répond pas à la question du PO. Vous aurez des ennuis si vous adoptez une définition particulière de ce qu'est une chaîne "vierge". En particulier, le comportement standard est celui qui str(None)produit 'None'une chaîne non vide.

Cependant, si vous devez traiter Noneand (espaces) comme des chaînes "vides", voici une meilleure façon:

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

Exemples:

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

Répond aux exigences @rouble sans casser le boolcomportement attendu des chaînes.

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

Je trouve cela élégant car il s'assure qu'il s'agit d'une chaîne et vérifie sa longueur:

def empty(mystring):
    assert isinstance(mystring, str)
    if len(mystring) == 0:
        return True
    else:
        return False
cardamome
la source
Attention, les assertions sont conçues comme un outil de débogage et sont optimisées si vous ne passez pas l' -Oindicateur ou définissez la PYTHONOPTIMIZEvariable env.
SilentVoid
2

Un autre moyen simple pourrait être de définir une fonction simple:

def isStringEmpty(inputString):
    if len(inputString) == 0:
        return True
    else:
        return False
tanzil
la source
3
la réponse de la cardamome est plus complète si nous voulons vérifier si l'entrée est une chaîne ou non
tanzil
1
not str(myString)

Cette expression est vraie pour les chaînes vides. Les chaînes non vides, les objets None et non-string produiront tous False, avec la mise en garde que les objets peuvent remplacer __str__ pour contrecarrer cette logique en renvoyant une valeur falsifiée.

Fax
la source
0

pour ceux qui s'attendent à un comportement comme l'apache StringUtils.isBlank ou Guava Strings.isNullOrEmpty :

if mystring and mystring.strip():
    print "not blank string"
else:
    print "blank string"
kommradHomer
la source
0

Lorsque vous lisez un fichier par lignes et que vous voulez déterminer quelle ligne est vide, assurez-vous que vous l'utiliserez .strip(), car il y a un nouveau caractère de ligne dans la ligne "vide":

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
la source
0
str = ""
if not str:
   print "Empty String"
if(len(str)==0):
   print "Empty String"
Tanmoy Datta
la source
0

Si vous utilisez simplement

not var1 

il n'est pas possible de différencier une variable booléenne Falsed'une chaîne vide '':

var1 = ''
not var1
> True

var1 = False
not var1
> True

Cependant, si vous ajoutez une condition simple à votre script, la différence est faite:

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

var1 = ''
not var1 and var1 != ''
> False
jberrio
la source
0

Dans le cas où cela serait utile à quelqu'un, voici une fonction rapide que j'ai construite pour remplacer les chaînes vides par des N / A dans des listes de listes (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

Ceci est utile pour publier des listes de listes dans une base de données mysql qui n'accepte pas les blancs pour certains champs (champs marqués comme NN dans le schéma. Dans mon cas, cela était dû à une clé primaire composite).

FlyingZebra1
la source
-1

J'ai fait quelques expériences avec des chaînes comme '', '', '\ n', etc. Je veux que isNotWhitespace soit True si et seulement si la variable foo est une chaîne avec au moins un caractère non blanc. J'utilise Python 3.6. Voici ce que j'ai fini avec:

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

Enveloppez-le dans une définition de méthode si vous le souhaitez.

Tom Stambaugh
la source
-3

Comme prmatta l'a indiqué ci-dessus, mais avec erreur.

def isNoneOrEmptyOrBlankString (myString):
    if myString:
        if not myString.strip():
            return True
        else:
            return False
    return False
Ombre
la source
Juste testé: Ses code retourne True pour ""et " "et False pour "a"(comme prévu). Votre code renvoie la même chose, sauf pour la chaîne vide qu'il renvoie True, ce qu'il ne devrait pas.
AbcAeffchen
trop fatigué: votre code renvoie Faux pour la chaîne vide.
AbcAeffchen
Ce code est faux. Vous renvoyez False si une chaîne est vide ou aucune.
rouble