Comment vérifier si une liste est vide?

3234

Par exemple, si passé les éléments suivants:

a = []

Comment puis-je vérifier s'il aest vide?

Rayon
la source

Réponses:

5507
if not a:
  print("List is empty")

L'utilisation de la booléenne implicite du vide listest assez pythonique.

Patrick
la source
1130
Jouer l'avocat du diable. Je ne comprends pas pourquoi cet idiome est considéré comme pythonique. «Explicite vaut mieux qu'implicite», n'est-ce pas? Cette vérification ne semble pas très explicite sur ce qui est en train de vérifier.
James McMahon
222
@JamesMcMahon - c'est un compromis entre explicitation et flexibilité de type. généralement, «être explicite» signifie ne pas faire de choses «magiques». d'un autre côté, "typage canard" signifie travailler avec des interfaces plus générales, plutôt que de rechercher explicitement des types. donc quelque chose comme if a == []force un type particulier ( () == []est False). ici, le consensus général semble être que la frappe de canard l'emporte (en fait, c'est __nonzero__l'interface pour tester la vacuité docs.python.org/reference/datamodel.html#object.__nonzero__ )
andrew cooke
38
Cette méthode ne fonctionne pas sur les tableaux numpy .. donc je pense que si len (a) == 0 est préférable à la fois en termes de "typage du canard" et d'implicité.
Mr.WorshipMe
10
La manière canonique de savoir si un tableau en C est vide consiste à déréférencer le premier élément et à voir s'il est nul, en supposant un tableau dont la terminaison est nulle. Sinon, comparer sa longueur à zéro est totalement inefficace si le tableau est d'une taille significative. En outre, en règle générale, vous n'allouez pas de mémoire à un tableau vide (le pointeur reste nul), il est donc inutile de tenter d'obtenir sa longueur. Je ne dis pas que len (a) == 0 n'est pas un bon moyen de le faire, il ne me crie tout simplement pas 'C' quand je le vois.
sleblanc
6
@BrennenSprimont, si elle n'est pas terminée par un caractère nul, alors vous connaissez déjà la longueur, qu'elle soit stockée dans une variable distincte ou que votre tableau soit enveloppé dans un conteneur qui suit la longueur. C ++, Java, C # ont de tels conteneurs et implémentent efficacement une méthode de "longueur". C n'a rien de tel , vous devez lancer le vôtre. Les tableaux C alloués statiquement ne sont que des pointeurs vers un espace mémoire qui est garanti d'avoir suffisamment d'espace pour stocker la quantité de données que vous avez demandée. Il n'y a rien de intégré dans C qui vous permettra de savoir combien vous avez déjà rempli cet espace.
sleblanc le
1160

La façon pythonique de le faire est tirée du guide de style PEP 8 (où Oui signifie «recommandé» et Non signifie «non recommandé»):

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

Yes: if not seq:
     if seq:

No:  if len(seq):
     if not len(seq):
Harley Holcombe
la source
49
La deuxième façon semble meilleure si vous souhaitez signaler que l' seqon s'attend à ce qu'il s'agisse d'une sorte d'objet de type liste.
BallpointBen
5
@BallpointBen qui, selon les partisans du pythonisme, devrait être implicite dans la façon dont la variable est nommée, autant que possible
axolotl
9
@BallpointBen essayez d'utiliser l'indication de type de Python pour signaler ce qu'une variable devrait être. Il a été introduit en 3.5.
Boris
8
numpy a brisé cet idiome ... seq = numpy.array ([1,2,3]) suivi de sinon seq déclenche une exception "ValueError: La valeur de vérité d'un tableau avec plus d'un élément est ambiguë. Utilisez a.any () ou a.all () "
Mr.WorshipMe
2
@jeronimo: Je pense que c'est un avertissement spécifique à lxml.
Harley Holcombe
770

Je le préfère explicitement:

if len(li) == 0:
    print('the list is empty')

De cette façon, il est clair à 100% qu'il lis'agit d'une séquence (liste) et nous voulons tester sa taille. Mon problème if not li: ...est que cela donne la fausse impression qui liest une variable booléenne.

Jabba
la source
91
Vérifier si la longueur d'une liste est égale à zéro, plutôt que de simplement vérifier si la liste est fausse, est moche et non pythonique. Quiconque est familier avec Python ne pensera pas du tout être liun bool, et ne s'en souciera pas. Si c'est important, vous devez ajouter un commentaire, pas plus de code.
Carl Smith,
21
Cela semble être un test inutilement précis, qui est souvent plus lent et est toujours moins lisible à mon humble avis. Au lieu de vérifier la taille d'un objet vide, pourquoi ne pas simplement vérifier s'il est vide?
John B
34
Quoi qu'il en soit, la raison pour laquelle cela est mauvais (et que violer des idiomes dans un langage avec des idiomes forts comme Python est mauvais en général) est qu'il signale au lecteur que vous vérifiez spécifiquement la longueur pour une raison quelconque (par exemple, parce que vous voulez Noneou 0lever une exception plutôt que de passer). Donc, quand vous le faites sans raison, qui est trompeur et cela signifie aussi que lorsque votre code fait besoin de faire la distinction, la distinction est invisible parce que vous avez « crié au loup » dans tout le reste de la source.
abarnert
18
Je pense que cela rallonge inutilement le code. Sinon, pourquoi ne pas être encore plus "explicite" avec if bool(len(li) == 0) is True:?
août 2015
11
@Jabba, ce sera O (1) dans de nombreux cas (ceux où vous travaillez avec les types de données intégrés), mais vous ne pouvez tout simplement pas vous y fier. Vous travaillez peut-être avec un type de données personnalisé qui n'a pas cette propriété. Vous pouvez également décider d'ajouter ce type de données personnalisé ultérieurement, après avoir déjà écrit ce code.
ralokt
325

Ceci est le premier hit google pour "tableau vide de test python" et des requêtes similaires, et d'autres personnes semblent généraliser la question au-delà des simples listes, donc j'ai pensé ajouter une mise en garde pour un type de séquence différent que beaucoup de gens Pourrait utiliser.

Les autres méthodes ne fonctionnent pas pour les tableaux NumPy

Vous devez être prudent avec les tableaux NumPy, car d'autres méthodes qui fonctionnent correctement pour lists ou d'autres conteneurs standard échouent pour les tableaux NumPy. J'explique pourquoi ci-dessous, mais en bref, la méthode préférée est d'utiliser size.

La méthode "pythonique" ne fonctionne pas: Partie 1

La méthode "pythonique" échoue avec les tableaux NumPy car NumPy essaie de convertir le tableau en un tableau de bools et if xessaie d'évaluer tous ces bools à la fois pour une sorte de valeur de vérité agrégée. Mais cela n'a aucun sens, vous obtenez donc ValueError:

>>> x = numpy.array([0,1])
>>> if x: print("x")
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

La méthode "pythonique" ne fonctionne pas: partie 2

Mais au moins le cas ci-dessus vous indique qu'il a échoué. S'il vous arrive d'avoir un tableau NumPy avec exactement un élément, l' ifinstruction "fonctionnera", dans le sens où vous n'obtiendrez pas d'erreur. Cependant, si cet élément se trouve être 0(ou 0.0, ou False, ...), l' ifinstruction entraînera incorrectement False:

>>> x = numpy.array([0,])
>>> if x: print("x")
... else: print("No x")
No x

Mais xexiste clairement et n'est pas vide! Ce résultat n'est pas ce que vous vouliez.

En utilisant len peut donner des résultats inattendus

Par exemple,

len( numpy.zeros((1,0)) )

renvoie 1, même si le tableau ne contient aucun élément.

La voie numpythonique

Comme expliqué dans la FAQ SciPy , la méthode correcte dans tous les cas où vous savez que vous avez un tableau NumPy est d'utiliser if x.size:

>>> x = numpy.array([0,1])
>>> if x.size: print("x")
x

>>> x = numpy.array([0,])
>>> if x.size: print("x")
... else: print("No x")
x

>>> x = numpy.zeros((1,0))
>>> if x.size: print("x")
... else: print("No x")
No x

Si vous n'êtes pas sûr qu'il s'agisse d' listun tableau, d'un tableau NumPy ou de quelque chose d'autre, vous pouvez combiner cette approche avec la réponse donnée par @dubiousjim pour vous assurer que le bon test est utilisé pour chaque type. Pas très "pythonique", mais il s'avère que NumPy a intentionnellement cassé la pythonicité dans au moins ce sens.

Si vous devez faire plus que simplement vérifier si l'entrée est vide et que vous utilisez d'autres fonctionnalités NumPy comme l'indexation ou les opérations mathématiques, il est probablement plus efficace (et certainement plus courant) de forcer l'entrée à être un tableau NumPy. Il y a quelques fonctions intéressantes pour le faire rapidement - le plus important numpy.asarray. Cela prend votre entrée, ne fait rien s'il s'agit déjà d'un tableau, ou encapsule votre entrée dans un tableau s'il s'agit d'une liste, d'un tuple, etc., et éventuellement la convertit en votre choix dtype. C'est donc très rapide chaque fois que cela peut être, et cela garantit que vous pouvez simplement supposer que l'entrée est un tableau NumPy. Nous utilisons généralement même le même nom, car la conversion en tableau ne le fera pas sortir de la portée actuelle :

x = numpy.asarray(x, dtype=numpy.double)

Cela fera fonctionner le x.sizechèque dans tous les cas que je vois sur cette page.

Mike
la source
62
Il convient de noter que ce n'est pas un défaut de Python, mais plutôt une rupture intentionnelle de contrat par numpy- numpyest une bibliothèque avec un cas d'utilisation très spécifique, et elle a une définition «naturelle» différente de ce qu'est la véracité d'un tableau pour le Norme Python pour les conteneurs. Il est logique d'optimiser pour ce cas, de la manière que les pathlibutilisations /des chemins concaténer au lieu de +- il est non standard, mais est logique dans le contexte.
Gareth Latty
9
D'accord. Mon point est juste qu'il est important de se rappeler que numpy a fait le choix de casser le typage du canard pour les expressions très courantes if xet les len(x)idiomes - et parfois cette rupture peut être très difficile à détecter et à déboguer.
Mike
22
Je ne sais pas, pour moi, si une méthode appelée len (x) ne retourne pas la longueur du tableau à cause d'hypothèses, son nom est mal conçu.
Dalton
11
Cette question n'a rien à voir avec les tableaux
numpy
19
@ppperry Oui, la question d'origine ne concernait pas les tableaux Numpy, mais lorsque vous travaillez avec ceux-ci et éventuellement des arguments de type canard, cette question devient très pertinente.
peterhil
223

Meilleur moyen de vérifier si une liste est vide

Par exemple, si passé les éléments suivants:

a = []

Comment puis-je vérifier si a est vide?

Réponse courte:

Placez la liste dans un contexte booléen (par exemple, avec une instruction ifor while). Il testera Falses'il est vide et Truesinon. Par exemple:

if not a:                           # do this!
    print('a is an empty list')

PEP 8

PEP 8 , le guide de style Python officiel pour le code Python dans la bibliothèque standard de Python, affirme:

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

Yes: if not seq:
     if seq:

No: if len(seq):
    if not len(seq):

Nous devons nous attendre à ce que le code de bibliothèque standard soit aussi performant et correct que possible. Mais pourquoi est-ce le cas et pourquoi avons-nous besoin de ces conseils?

Explication

Je vois souvent du code comme celui-ci de programmeurs expérimentés nouveaux sur Python:

if len(a) == 0:                     # Don't do this!
    print('a is an empty list')

Et les utilisateurs de langues paresseuses peuvent être tentés de le faire:

if a == []:                         # Don't do this!
    print('a is an empty list')

Celles-ci sont correctes dans leurs autres langues respectives. Et cela est même sémantiquement correct en Python.

Mais nous le considérons comme non-Pythonic car Python prend en charge ces sémantiques directement dans l'interface de l'objet liste via la contrainte booléenne.

À partir des documents (et notez spécifiquement l'inclusion de la liste vide []):

Par défaut, un objet est considéré comme vrai, sauf si sa classe définit une __bool__()méthode qui renvoie Falseou une __len__()méthode qui renvoie zéro, lorsqu'elle est appelée avec l'objet. Voici la plupart des objets intégrés considérés comme faux:

  • constantes définies comme fausses: Noneet False.
  • zéro de tout type numérique: 0, 0.0, 0j, Decimal(0),Fraction(0, 1)
  • séquences vides et collections: '', (), [], {}, set(),range(0)

Et la documentation du modèle de données:

object.__bool__(self)

Appelé à mettre en œuvre des tests de valeur de vérité et l'opération intégrée bool(); devrait revenir Falseou True. Lorsque cette méthode n'est pas définie, elle __len__()est appelée, si elle est définie, et l'objet est considéré comme vrai si son résultat n'est pas nul. Si une classe ne définit ni __len__() ni __bool__(), toutes ses instances sont considérées comme vraies.

et

object.__len__(self)

Appelé pour implémenter la fonction intégrée len(). Doit renvoyer la longueur de l'objet, un entier> = 0. En outre, un objet qui ne définit pas une __bool__()méthode et dont la __len__()méthode renvoie zéro est considéré comme faux dans un contexte booléen.

Donc au lieu de ça:

if len(a) == 0:                     # Don't do this!
    print('a is an empty list')

ou ca:

if a == []:                     # Don't do this!
    print('a is an empty list')

Faites ceci:

if not a:
    print('a is an empty list')

Faire ce qui est Pythonic porte généralement ses fruits en termes de performances:

Est-ce payant? (Notez que moins de temps pour effectuer une opération équivalente est mieux :)

>>> import timeit
>>> min(timeit.repeat(lambda: len([]) == 0, repeat=100))
0.13775854044661884
>>> min(timeit.repeat(lambda: [] == [], repeat=100))
0.0984637276455409
>>> min(timeit.repeat(lambda: not [], repeat=100))
0.07878462291455435

Pour l'échelle, voici le coût de l'appel de la fonction et de la construction et du retour d'une liste vide, que vous pourriez soustraire des coûts des contrôles de vide utilisés ci-dessus:

>>> min(timeit.repeat(lambda: [], repeat=100))
0.07074015751817342

Nous voyons que soit vérifier la longueur avec la fonction intégréelen par rapport à 0 ou la vérification par rapport à une liste vide est beaucoup moins performante que l'utilisation de la syntaxe intégrée du langage comme documenté.

Pourquoi?

Pour le len(a) == 0chèque:

Python doit d'abord vérifier les globaux pour voir s'il lenest ombré.

Ensuite, il doit appeler la fonction, charger 0 et faire la comparaison d'égalité en Python (au lieu de C):

>>> import dis
>>> dis.dis(lambda: len([]) == 0)
  1           0 LOAD_GLOBAL              0 (len)
              2 BUILD_LIST               0
              4 CALL_FUNCTION            1
              6 LOAD_CONST               1 (0)
              8 COMPARE_OP               2 (==)
             10 RETURN_VALUE

Et pour le [] == [] cela, il doit créer une liste inutile, puis, encore une fois, faire l'opération de comparaison dans la machine virtuelle de Python (par opposition à C)

>>> dis.dis(lambda: [] == [])
  1           0 BUILD_LIST               0
              2 BUILD_LIST               0
              4 COMPARE_OP               2 (==)
              6 RETURN_VALUE

La méthode "Pythonic" est une vérification beaucoup plus simple et plus rapide car la longueur de la liste est mise en cache dans l'en-tête de l'instance d'objet:

>>> dis.dis(lambda: not [])
  1           0 BUILD_LIST               0
              2 UNARY_NOT
              4 RETURN_VALUE

Preuve de la source C et documentation

PyVarObject

Il s'agit d'une extension PyObjectqui ajoute le ob_sizechamp. Ceci n'est utilisé que pour les objets qui ont une certaine notion de longueur. Ce type n'apparaît pas souvent dans l'API Python / C. Il correspond aux domaines définis par l'expansion duPyObject_VAR_HEAD macro.

À partir de la source c dans Include / listobject.h :

typedef struct {
    PyObject_VAR_HEAD
    /* Vector of pointers to list elements.  list[0] is ob_item[0], etc. */
    PyObject **ob_item;

    /* ob_item contains space for 'allocated' elements.  The number
     * currently in use is ob_size.
     * Invariants:
     *     0 <= ob_size <= allocated
     *     len(list) == ob_size

Réponse aux commentaires:

Je voudrais souligner que cela est également vrai pour le cas non vide bien que son assez laid comme avec l=[]alors %timeit len(l) != 090,6 ns ± 8,3 ns, %timeit l != []55,6 ns ± 3,09, %timeit not not l38,5 ns ± 0,372. Mais personne ne pourra en profiter not not lmalgré le triple de la vitesse. Ça a l'air ridicule. Mais la vitesse l'emporte,
je suppose que le problème est de tester avec timeit car c'est juste if l:suffisant mais %timeit bool(l)donne étonnamment 101 ns ± 2,64 ns. Intéressant, il n'y a aucun moyen de contraindre à bool sans cette pénalité. %timeit lest inutile car aucune conversion ne se produirait.

La magie IPython,, %timeitn'est pas entièrement inutile ici:

In [1]: l = []                                                                  

In [2]: %timeit l                                                               
20 ns ± 0.155 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

In [3]: %timeit not l                                                           
24.4 ns ± 1.58 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [4]: %timeit not not l                                                       
30.1 ns ± 2.16 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

Nous pouvons voir qu'il y a un peu de coût linéaire pour chaque supplémentaire notici. Nous voulons voir les coûts, toutes choses égales par ailleurs , c'est-à-dire toutes choses égales par ailleurs - où tout le reste est minimisé autant que possible:

In [5]: %timeit if l: pass                                                      
22.6 ns ± 0.963 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [6]: %timeit if not l: pass                                                  
24.4 ns ± 0.796 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [7]: %timeit if not not l: pass                                              
23.4 ns ± 0.793 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

Examinons maintenant le cas d'une liste non vide:

In [8]: l = [1]                                                                 

In [9]: %timeit if l: pass                                                      
23.7 ns ± 1.06 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [10]: %timeit if not l: pass                                                 
23.6 ns ± 1.64 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [11]: %timeit if not not l: pass                                             
26.3 ns ± 1 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

Ce que nous pouvons voir ici, c'est que peu importe que vous passiez dans un bool à la vérification de l'état ou à la liste elle-même, et si quoi que ce soit, donner la liste telle quelle est plus rapide.

Python est écrit en C; il utilise sa logique au niveau C. Tout ce que vous écrivez en Python sera plus lent. Et ce sera probablement plus lent, à moins que vous n'utilisiez directement les mécanismes intégrés à Python.

Aaron Hall
la source
Je voudrais souligner que cela est également vrai pour le cas non vide bien que son assez laid comme avec l=[]alors %timeit len(l) != 090,6 ns ± 8,3 ns, %timeit l != []55,6 ns ± 3,09, %timeit not not l38,5 ns ± 0,372. Mais personne ne peut en profiter not not lmalgré le triple de la vitesse. Ça a l'air ridicule. Mais la vitesse l'emporte
Gregory Morse
Je suppose que le problème est de tester avec timeit car c'est juste if l:suffisant mais %timeit bool(l)donne étonnamment 101 ns ± 2,64 ns. Intéressant, il n'y a aucun moyen de contraindre à bool sans cette pénalité. %timeit lest inutile car aucune conversion ne se produirait.
Gregory Morse
139

Une liste vide est elle-même considérée comme fausse dans les tests de valeur réelle (voir la documentation python ):

a = []
if a:
     print "not empty"

@Daren Thomas

EDIT: Un autre point contre le test de la liste vide comme faux: qu'en est-il du polymorphisme? Vous ne devriez pas dépendre qu'une liste soit une liste. Il devrait juste charlataner comme un canard - comment allez-vous faire en sorte que votre duckCollection pique '' False '' quand il ne contient aucun élément?

Votre duckCollection devrait implémenter __nonzero__ou __len__si le a: fonctionnera sans problème.

Peter Hoffmann
la source
Étrange comment [] == Falsesera évalué à faux cependant
information_interchange
@information_interchange Si vous souhaitez vérifier explicitement la véracité d'une valeur, utilisez bool(). bool([]) == Falsesera évalué Truecomme prévu.
7h29
103

La réponse (acceptée) de Patrick est juste: if not a:c'est la bonne façon de le faire. La réponse de Harley Holcombe est juste que c'est dans le guide de style PEP 8. Mais ce qu'aucune des réponses n'explique, c'est pourquoi c'est une bonne idée de suivre l'idiome - même si vous trouvez personnellement qu'il n'est pas suffisamment explicite ou déroutant pour les utilisateurs de Ruby ou autre.

Le code Python et la communauté Python ont des idiomes très forts. Suivre ces idiomes rend votre code plus facile à lire pour toute personne expérimentée en Python. Et lorsque vous violez ces idiomes, c'est un signal fort.

Il est vrai que if not a:cela ne distingue pas les listes vides de None, ou 0 numérique, ou les tuples vides, ou les types de collection créés par l'utilisateur vides, ou les types de collection vides pas tout à fait créés par l'utilisateur, ou le tableau NumPy à un seul élément agissant comme des scalaires avec falsey valeurs, etc. Et parfois, il est important d'être explicite à ce sujet. Et dans ce cas, vous savez sur quoi vous voulez être explicite, vous pouvez donc tester exactement cela. Par exemple, if not a and a is not None:signifie «tout ce qui est falsey sauf None», tandis que if len(a) != 0:signifie «uniquement les séquences vides - et tout ce qui n'est pas une séquence est ici une erreur», etc. En plus de tester exactement ce que vous voulez tester, cela signale également au lecteur que ce test est important.

Mais quand vous n'avez rien à expliquer, rien d'autre que if not a:trompe le lecteur. Vous signalez quelque chose d'aussi important quand ce n'est pas le cas. (Vous pouvez également rendre le code moins souple, ou plus lent, ou autre chose, mais c'est tout moins important.) Et si vous habituellement induire en erreur le lecteur comme celui - ci, lorsque vous avez besoin de faire une distinction, il va passer inaperçu parce que vous avez "pleuré le loup" partout dans votre code.

abarnert
la source
78

Pourquoi vérifier du tout?

Personne ne semble avoir abordé la question de votre besoin de tester la liste en premier lieu. Parce que vous n'avez fourni aucun contexte supplémentaire, je peux imaginer que vous n'avez peut-être pas besoin de faire cette vérification en premier lieu, mais que vous n'êtes pas familier avec le traitement de liste en Python.

Je dirais que la façon la plus pythonique est de ne pas vérifier du tout, mais plutôt de simplement traiter la liste. De cette façon, il fera la bonne chose, vide ou plein.

a = []

for item in a:
    <do something with item>

<rest of code>

Cela présente l'avantage de manipuler tout contenu d' un , sans nécessiter un contrôle spécifique de la vacuité. Si a est vide, le bloc dépendant ne s'exécutera pas et l'interpréteur passera à la ligne suivante.

Si vous avez réellement besoin de vérifier le tableau pour le vide, les autres réponses sont suffisantes.

MrWonderful
la source
3
Le fait est que vérifier si la liste est vide est assez important, du moins pour moi. Avez-vous pensé s'il y avait un script à l'intérieur <rest of code>qui pourrait utiliser le résultat de la forboucle? Ou utiliser directement certaines valeurs dans a? En effet, si le script est conçu pour s'exécuter avec une entrée strictement contrôlée, la vérification peut être un peu inutile. Mais dans la plupart des cas, l'entrée varie et une vérification est généralement meilleure.
Amarth Gûl
Respectueusement, non. Ce que j'ai considéré était quelqu'un qui ne connaissait pas suffisamment Python pour savoir que «si <list>:» était la bonne réponse, a demandé comment vérifier une liste vide. Ensuite, j'ai remarqué BEAUCOUP de réponses qui offraient des opinions différentes, mais aucune ne semblait répondre au besoin initial. C'est ce que j'ai essayé de faire avec ma réponse: demandez-leur d'examiner la nécessité avant de continuer. Je pense que je l'ai suggéré de manière explicite dans ma réponse.
MrWonderful
@ AmarthGûl - Comment obtenir les résultats de la boucle for vers le script à l'intérieur du <reste du code> à traiter? Dans une liste, peut-être? Ou peut-être un dicton? Si c'est le cas, la même logique s'applique. Je ne comprends pas comment la saisie de variables pourrait avoir un effet dans tout type de code raisonnablement conçu, où le traitement d'une liste vide serait une mauvaise idée.
MrWonderful
Un peu vieux mais si vous vérifiiez simplement si la liste était vide, pour une liste non vide votre code répète le processus encore et encore lorsque OP recherche simplement une opération de vérification. Imaginez un scénario pire pour ce code à l'approche de l'infini ...
DJK
7
@DJK - Non, je pense que vous le manquez toujours. Vraisemblablement, vous voulez FAIRE quelque chose avec une liste, si vous en avez une. Que feriez-vous différemment s'il était vide? Vous revenez tôt? Et s'il n'est pas vide? traiter? Le fait est, cependant, que vous n'avez probablement pas besoin de vérifier une liste vide, il suffit de l'itérer et de faire ce que vous alliez faire avec les éléments. S'il n'y a pas d'éléments, vous tombez. S'il y a des éléments, vous les traitez comme vous le souhaitez. Le point n'est PAS d'utiliser l'exemple POUR une vérification vide mais plutôt de NE PAS vérifier du tout, il suffit de traiter la liste.
MrWonderful
40

J'avais écrit:

if isinstance(a, (list, some, other, types, i, accept)) and not a:
    do_stuff

qui a été voté -1. Je ne sais pas si c'est parce que les lecteurs se sont opposés à la stratégie ou pensaient que la réponse n'était pas utile telle qu'elle était présentée. Je ferai comme si c'était le dernier, car --- tout ce qui compte comme "pythonique" --- c'est la bonne stratégie. À moins que vous ne l'ayez déjà exclu ou que vous ne soyez prêt à traiter des cas où a, par exemple False, vous avez besoin d'un test plus restrictif que juste if not a:. Vous pouvez utiliser quelque chose comme ceci:

if isinstance(a, numpy.ndarray) and not a.size:
    do_stuff
elif isinstance(a, collections.Sized) and not a:
    do_stuff

le premier test est en réponse à la réponse de @ Mike, ci-dessus. La troisième ligne pourrait également être remplacée par:

elif isinstance(a, (list, tuple)) and not a:

si vous souhaitez uniquement accepter des instances de types particuliers (et leurs sous-types), ou avec:

elif isinstance(a, (list, tuple)) and not len(a):

Vous pouvez vous en sortir sans la vérification de type explicite, mais uniquement si le contexte environnant vous assure déjà que ac'est une valeur des types que vous êtes prêt à gérer, ou si vous êtes sûr que les types que vous n'êtes pas prêt à gérer vont pour générer des erreurs (par exemple, TypeErrorsi vous appelez lenune valeur pour laquelle elle n'est pas définie) que vous êtes prêt à gérer. En général, les conventions "pythoniques" semblent aller dans ce sens. Pressez-le comme un canard et laissez-le lever une DuckError s'il ne sait pas charlatan. Vous devez encore penserCependant, aux hypothèses de type que vous faites et si les cas que vous n'êtes pas prêt à gérer correctement vont vraiment se tromper aux bons endroits. Les tableaux Numpy sont un bon exemple où il suffit de s'appuyer aveuglément surlen ou le transtypage booléen peut ne pas faire exactement ce que vous attendez.

dubiousjim
la source
3
Il est assez rare que vous ayez une liste exhaustive de 6 types que vous souhaitez accepter et que vous ne soyez flexible pour aucun autre type. Lorsque vous avez besoin de ce genre de chose, vous voulez probablement un ABC. Dans ce cas, ce serait probablement l'un des ABC stdlib, comme collections.abc.Sizedou collections.abc.Sequence, mais ce pourrait être celui que vous écrivez vous-même et register(list)sur. Si vous avez réellement du code où il est important de distinguer les vides des autres falsey, et aussi de distinguer les listes et les tuples de toute autre séquence, alors c'est correct, mais je ne pense pas que vous ayez un tel code.
abarnert
13
La raison pour laquelle les gens n'aiment pas cela, c'est parce que c'est tout à fait inutile dans la plupart des cas. Python est un langage de type canard, et ce niveau de codage défensif entrave activement cela. L'idée derrière le système de type de Python est que les choses devraient fonctionner aussi longtemps que l'objet passe dans les fonctions comme il le doit. En effectuant des vérifications de type explicites, vous forcez l'appelant à utiliser des types spécifiques, allant à l'encontre du grain même de la langue. Bien que de telles choses soient parfois nécessaires (pour éviter que les chaînes ne soient traitées comme des séquences), de tels cas sont rares et presque toujours préférables comme listes noires.
Gareth Latty
1
Si vous voulez vraiment vérifier que la valeur est exactement []et non quelque chose de faux d'un autre type, alors il if a == []:est sûrement nécessaire, plutôt que de se moquer d'isinstance.
RemcoGerlich
2
Il existe cependant des contraintes automatiques ==. Du haut de ma tête, je ne peux en identifier aucun []. [] == ()par exemple retourne False. Mais par exemple frozenset()==set()revient True. Il vaut donc au moins réfléchir à la possibilité de contraindre [](ou vice versa) certains types indésirables lors de cette opération a == [].
dubiousjim
@RemcoGerlich - isinstance () est toujours préférable à la construction d'une liste vide à comparer. De plus, comme un autre l'a souligné, l'opérateur d'égalité peut invoquer la conversion implicite de certains types, ce qui peut être indésirable. Il n'y a aucune raison de coder "a == []" et ce code serait définitivement signalé comme un défaut dans toute révision de code à laquelle j'ai participé. L'utilisation de l'outil approprié fourni par le langage ne devrait pas être considérée comme , "mais plutôt" une bonne technique de programmation ".
MrWonderful
29

De la documentation sur les tests de valeur de vérité:

Toutes les valeurs autres que celles répertoriées ici sont prises en compte True

  • None
  • False
  • zéro de tout type numérique, par exemple, 0, 0.0, 0j.
  • toute séquence vide, par exemple, '', (), [].
  • tout mappage vide, par exemple {},.
  • instances de classes définies par l'utilisateur, si la classe définit une méthode __bool__()ou __len__(), lorsque cette méthode retourne le zéro entier ou la valeur booléenne False.

Comme on peut le voir, une liste vide []est fausse , donc faire ce qui serait fait pour une valeur booléenne semble plus efficace:

if not a:
    print('"a" is empty!')
Sнаđошƒаӽ
la source
@DJ_Stuffy_K affirme quoi dans les tests unitaires, une liste vide? Utilisez simplement assert(not myList). Si vous souhaitez également affirmer que l'objet est un list, vous pouvez utiliser assertIsInstance().
Sнаđошƒаӽ
24

Voici quelques façons de vérifier si une liste est vide:

a = [] #the list

1) La manière pythonique assez simple:

if not a:
    print("a is empty")

En Python, les conteneurs vides tels que les listes, les tuples, les ensembles, les dict, les variables, etc. sont considérés comme False. On pourrait simplement traiter la liste comme un prédicat ( renvoyer une valeur booléenne ). Et une Truevaleur indiquerait qu'il n'est pas vide.

2) Une manière très explicite: utiliser le len()pour trouver la longueur et vérifier si elle est égale à 0:

if len(a) == 0:
    print("a is empty")

3) Ou en le comparant à une liste vide anonyme:

if a == []:
    print("a is empty")

4) Une autre façon encore stupide de faire est d'utiliser exceptionet iter():

try:
    next(iter(a))
    # list has elements
except StopIteration:
    print("Error: a is empty")
Inconnu
la source
20

Je préfère ce qui suit:

if a == []:
   print "The list is empty."
verix
la source
37
Cela va être plus lent, car vous instanciez une liste vide supplémentaire inutilement.
Carl Meyer
32
ceci est moins lisible if not a:et se casse plus facilement. Veuillez ne pas le faire.
devsnd
Il y a un bon point soulevé plus tôt () == []est également égal à faux. Bien que j'aime la façon dont cette implémentation lit if not a:tous les cas, si vous attendez vraiment une liste, votre exemple devrait être suffisant.
Une étoile
19

Méthode 1 (préférée):

if not a : 
   print ("Empty") 

Méthode 2:

if len(a) == 0 :
   print( "Empty" )

Méthode 3:

if a == [] :
  print ("Empty")
Vikrant
la source
12
def list_test (L):
    if   L is None  : print('list is None')
    elif not L      : print('list is empty')
    else: print('list has %d elements' % len(L))

list_test(None)
list_test([])
list_test([1,2,3])

Il est parfois bon de tester Noneséparément et pour le vide car ce sont deux états différents. Le code ci-dessus produit la sortie suivante:

list is None 
list is empty 
list has 3 elements

Même si cela ne vaut rien, c'est Nonefaux. Donc, si vous ne voulez pas séparer le test de None-ness, vous n'avez pas à le faire.

def list_test2 (L):
    if not L      : print('list is empty')
    else: print('list has %d elements' % len(L))

list_test2(None)
list_test2([])
list_test2([1,2,3])

produit attendu

list is empty
list is empty
list has 3 elements
Tagar
la source
8

De nombreuses réponses ont été données, et beaucoup d'entre elles sont plutôt bonnes. Je voulais juste ajouter que le chèque

not a

passera également pour Noneet d'autres types de structures vides. Si vous voulez vraiment rechercher une liste vide, vous pouvez le faire:

if isinstance(a, list) and len(a)==0:
    print("Received an empty list")
HackerBoss
la source
Il est possible que cela lève une exception, s'il ane s'agit pas d'une liste et aqu'aucune méthode n'est __len__implémentée. Je recommanderais:if isinstance(obj, list): if len(obj) == 0: print '...'
Sven Krüger
4
@ SvenKrüger non. L'opérateur andest paresseux en Python. Rien après ne andsera exécuté si la condition précédente andest False.
ElmoVanKielmo
7

nous pourrions utiliser un simple sinon:

item_list=[]
if len(item_list) == 0:
    print("list is empty")
else:
    print("list is not empty")
l. Zhang
la source
5
-1 - Pour éviter toute confusion, n'utilisez pas de mots réservés pour les noms de variables ou vous risquez d'obtenir un comportement surprenant la prochaine fois que vous essayez d'appeler, par exemple "list ()" ... quelque chose comme "TypeError: l'objet" list "est pas appelable "ou certains autres.
MrWonderful
6

Si vous souhaitez vérifier si une liste est vide:

l = []
if l:
    # do your stuff.

Si vous souhaitez vérifier si toutes les valeurs de la liste sont vides. Mais ce sera Truepour une liste vide:

l = ["", False, 0, '', [], {}, ()]
if all(bool(x) for x in l):
    # do your stuff.

Si vous souhaitez utiliser les deux cas ensemble:

def empty_list(lst):
    if len(lst) == 0:
        return False
    else:
        return all(bool(x) for x in l)

Vous pouvez maintenant utiliser:

if empty_list(lst):
    # do your stuff.
Rahul
la source
1
all (bool (x) for x in l) est True pour une liste vide
gberger
5

S'inspirant de la solution de @ dubiousjim, je propose d'utiliser une vérification générale supplémentaire pour savoir si c'est quelque chose d'itérable

import collections
def is_empty(a):
    return not a and isinstance(a, collections.Iterable)

Remarque: une chaîne est considérée comme itérable. - ajoutez and not isinstance(a,(str,unicode))si vous voulez que la chaîne vide soit exclue

Tester:

>>> is_empty('sss')
False
>>> is_empty(555)
False
>>> is_empty(0)
False
>>> is_empty('')
True
>>> is_empty([3])
False
>>> is_empty([])
True
>>> is_empty({})
True
>>> is_empty(())
True
AndreyS Scherbakov
la source
1
Overbroad; c'est simplement demander si une liste est vide, pas si quelque chose est un itérable vide.
pppery
1
Si je n'étais pas satisfait if a:, ce serait parce que je voulais une exception s'il ane s'agissait pas d'une sorte de conteneur. (Être un itérable permet également des itérateurs, qui ne peuvent pas être utilement testés pour la vacuité.)
Davis Herring
5
print('not empty' if a else 'empty')

un peu plus pratique:

a.pop() if a else None

et version shertest:

if a: a.pop() 
Andrey Suglobov
la source
4

A partir de python3, vous pouvez utiliser

a == []

pour vérifier si la liste est vide

EDIT: Cela fonctionne aussi avec python2.7 ..

Je ne sais pas pourquoi il y a tant de réponses compliquées. C'est assez clair et simple

Tessaracter
la source
1
veuillez donner plus d'explications sur la façon dont cela fonctionne sans écrire "si"?
ganeshdeshmukh
3
Ce n'est pas pythonique ni un exemple complet. De plus, il instancie une liste vide à chaque fois qu'elle est rencontrée. Ne fais pas ça.
MrWonderful
@MrWonderful, il n'instancie pas une liste vide à chaque fois. Il vérifie simplement si la liste existante aest vide ou non.
Tessaracter
@MrWonderful Je ne comprends pas ce qui en faitpythonic
Tessaracter
@ganeshdeshmukh si vous l'utilisez a==[], affichera true sur le terminal python si a est vide. Sinon, il affichera Faux. Vous pouvez l'utiliser dans une condition if égalementif(a==[])
Tessaracter
3

Vous pouvez même essayer d'utiliser bool () comme ceci

    a = [1,2,3];
    print bool(a); # it will return True
    a = [];
    print bool(a); # it will return False

J'adore cette façon de vérifier que la liste est vide ou non.

Très pratique et utile.

Sunil Lulla
la source
4
Pour ceux (comme moi) qui ne le savaient pas, bool()convertit une variable Python en booléen afin que vous puissiez stocker la véracité ou la fausseté d'une valeur sans avoir à utiliser une instruction if. Je pense que c'est moins lisible que d'utiliser simplement un conditionnel comme la réponse acceptée, mais je suis sûr qu'il existe d'autres bons cas d'utilisation pour cela.
Galen Long
Ceci est utilisable dans une expression et est plus concis.
qneill
3

Utilisez simplement is_empty () ou faites une fonction comme: -

def is_empty(any_structure):
    if any_structure:
        print('Structure is not empty.')
        return True
    else:
        print('Structure is empty.')
        return False  

Il peut être utilisé pour n'importe quelle structure de données comme une liste, des tuples, un dictionnaire et bien d'autres. Par ceux-ci, vous pouvez l'appeler plusieurs fois en utilisant simplement is_empty(any_structure).

Vineet Jain
la source
3
Le nom is_emptysuggère qu'il renvoie quelque chose. Mais si c'était le cas, ce serait juste quelque chose bool(any_structure), que vous devriez utiliser à la place ( quand vous en avez besoin bool).
Davis Herring
4
Pourquoi voulons-nous une variation sur boolcela (également) imprime les messages sur la sortie standard?
Davis Herring
@DavisHerring Nous avons toujours deux choix en premier est d'imprimer en utilisant la fonction autre utilise la boolvariable de retour . Le choix vous appartient. J'écris les deux pour que vous puissiez choisir entre eux.
Vineet Jain
3

Un moyen simple est de vérifier que la longueur est égale à zéro.

if len(a) == 0:
    print("a is empty")
Ashiq Imran
la source
1

La valeur de vérité d'une liste vide est Falsealors qu'elle l' est pour une liste non vide True.

MiloMinderbinder
la source
1

Ce qui m'a amené ici est un cas d'utilisation particulier: je voulais en fait une fonction pour me dire si une liste est vide ou non. Je voulais éviter d'écrire ma propre fonction ou d'utiliser une expression lambda ici (car il semblait que cela devrait être assez simple):

foo = itertools.takewhile(is_not_empty, (f(x) for x in itertools.count(1)))

Et, bien sûr, il existe une manière très naturelle de le faire:

foo = itertools.takewhile(bool, (f(x) for x in itertools.count(1)))

Bien sûr, ne l' utilisez pasbool dans if(c.- à -d. if bool(L):) Parce que c'est implicite. Mais, pour les cas où "n'est pas vide" est explicitement nécessaire en tant que fonction, boolc'est le meilleur choix.

Vedran Šego
la source
1

Pour vérifier si une liste est vide ou non, vous pouvez utiliser les deux méthodes suivantes. Mais rappelez-vous, nous devons éviter la façon de vérifier explicitement un type de séquence (c'est une less pythonicfaçon):

def enquiry(list1): 
    if len(list1) == 0: 
        return 0
    else: 
        return 1

# ––––––––––––––––––––––––––––––––

list1 = [] 

if enquiry(list1): 
    print ("The list isn't empty") 
else: 
    print("The list is Empty") 

# Result: "The list is Empty".

La deuxième façon est more pythoniccelle-là. Cette méthode est un moyen implicite de vérification et beaucoup plus préférable que la précédente.

def enquiry(list1): 
    if not list1: 
        return True
    else: 
        return False

# ––––––––––––––––––––––––––––––––

list1 = [] 

if enquiry(list1): 
    print ("The list is Empty") 
else: 
    print ("The list isn't empty") 

# Result: "The list is Empty"

J'espère que cela t'aides.

Andy
la source