variable - savoir si un dictionnaire est vide python




Comment vérifier si une liste est vide? (20)

Par exemple, si passé ce qui suit:

a = []

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


Meilleur moyen de vérifier si une liste est vide

Par exemple, si passé ce qui suit:

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 if ou while ). Il testera False s'il est vide et True sinon. Par exemple:

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

Appel à l'autorité

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 devrions 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 fréquemment du code comme celui-ci de programmeurs expérimentés qui découvrent 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 considérons cela comme non-Pythonique car Python supporte cette sémantique directement dans l'interface de l'objet liste via la contrainte booléenne.

Dans la docs (et notez en particulier l'inclusion de la liste vide, [] ):

Par défaut, un objet est considéré comme vrai sauf si sa classe définit une __bool__() qui renvoie False ou une __len__() 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:

  • les constantes définies comme étant fausses: None et False .
  • zéro de n'importe quel type numérique: 0 , 0.0 , 0j , Decimal(0) , Fraction(0, 1)
  • Séquences et collections vides: '' , () , [] , {} , set() , range(0)

Et la documentation sur les modèles de données:

object.__bool__(self)

Appelé pour mettre en œuvre le test de valeur de vérité et l'opération intégrée bool() ; devrait retourner False ou True . Si cette méthode n'est pas définie, __len__() est appelée, si elle est définie, et l'objet est considéré comme vrai si son résultat est différent de zéro. 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 de méthode __bool__() et dont la méthode __len__() renvoie zéro est considéré comme faux dans un contexte booléen.

Donc au lieu de cela:

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

Faire ceci:

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

Faire ce qui est Pythonic est généralement rentable en performance:

Est-ce que ça paye? (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 création et du renvoi d'une liste vide, que vous pouvez soustraire du coût des contrôles de vide utilisés ci-dessus:

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

Nous voyons que vérifier la longueur avec la fonction intégrée len par rapport à 0 ou vérifier une liste vide est beaucoup moins performant que d’utiliser la syntaxe intégrée du langage telle que documentée.

Pourquoi?

Pour le len(a) == 0 vérifier:

D'abord, Python doit vérifier les globales pour voir si len est 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 [] == [] il doit créer une liste inutile, puis effectuer à nouveau 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 de la documentation

PyVarObject

C'est une extension de PyObject qui ajoute le champ ob_size . Ceci n'est utilisé que pour les objets qui ont une notion de longueur. Ce type n'apparaît pas souvent dans l'API Python / C. Il correspond aux champs définis par le développement de la macro PyObject_VAR_HEAD .

À 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

J'ai aimé faire des recherches à ce sujet et j'ai passé beaucoup de temps à préparer mes réponses. Si vous pensez que je laisse quelque chose, merci de me le faire savoir dans un commentaire.


Pourquoi vérifier du tout?

Personne ne semble s'être interrogé sur la nécessité de tester la liste en premier lieu. Étant donné que vous n'avez fourni aucun contexte supplémentaire, j'imagine que vous n'avez peut-être pas besoin de faire cette vérification, mais que vous ne connaissez pas le traitement de liste en Python.

Je dirais que le moyen le plus pythonique est de ne pas vérifier du tout, mais de simplement traiter la liste. De cette façon, il fera le bon choix, qu'il soit vide ou plein.

a = []

for item in a:
    <do something with item>

<rest of code>

Cela présente l’avantage de manipuler le contenu d’ un objet tout en n’exigeant pas de vérification spécifique de la vacuité. Si a est vide, le bloc dépendant ne sera pas exécuté et l'interpréteur passera à la ligne suivante.

Si vous devez réellement vérifier le tableau pour la vacuité, les autres réponses sont suffisantes.


De la documentation sur le test de valeur de vérité:

Toutes les valeurs autres que celles répertoriées ici sont considérées comme 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 __bool__() ou __len__() , lorsque cette méthode renvoie le nombre entier zéro ou la valeur booléenne False .

Comme on peut le constater, une liste vide [] est une erreur , alors ce que l'on ferait d'une valeur booléenne semble plus efficace:

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

J'ai vu le ci-dessous comme préféré:

if not a:
    print("The list is empty or null")

Je le préfère explicitement:

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

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


Je préfère ce qui suit:

if a == []:
   print "The list is empty."

Lisible et vous n'avez pas à vous soucier d'appeler une fonction comme len() pour parcourir la variable. Bien que je ne sois pas tout à fait sûr de ce que la notation BigO de quelque chose comme celle-ci est ... mais Python est tellement rapide que je doute que cela aurait de l'importance si a n'était pas gigantesque.


La manière simple vérifie que la longueur est égale à zéro.

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

Python est très uniforme dans le traitement de la vacuité. Compte tenu de ce qui suit:

a = []

.
.
.

if a:
   print("List is not empty.")
else:
   print("List is empty.")

Il vous suffit de vérifier la liste avec une instruction "if" pour voir si elle est vide. D'après ce que j'ai lu et appris, c'est le moyen "Pythonique" de voir si une liste ou un tuple est vide.


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. - add and not isinstance(a,(str,unicode)) si vous souhaitez 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

Un autre moyen simple pourrait être

a = []
if len(a) == 0:
  print("Empty")
else:
  print(" Not empty")

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

a = [] #the list

1) La manière simple et pythonique:

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

En Python, les conteneurs vides tels que des listes, des nuplets, des ensembles, des dict, des variables, etc. sont vus comme False . On pourrait simplement traiter la liste comme un prédicat ( renvoyer une valeur booléenne ). Et une valeur True indiquerait que ce n'est pas vide.

2) Une manière bien explicite: en utilisant 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 idiote de faire consiste à utiliser exception et iter() :

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

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'aime cette façon pour la liste de contrôle est vide ou non.

Très pratique et utile.



D'autres personnes semblent généraliser la question au-delà des listes, alors j'ai pensé ajouter une mise en garde pour un type de séquence différent que beaucoup de gens pourraient utiliser, d'autant plus qu'il s'agit du premier hit Google pour "tableau vide de test python" .

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

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

La méthode "pythonique" ne fonctionne pas: première partie

La méthode "pythonique" échoue avec les tableaux numpy car numpy essaie de convertir le tableau en un tableau de bool s, et if x essaie d'évaluer tous ces bool s en même temps pour une sorte de valeur de vérité agrégée. Mais cela n’a aucun sens, alors vous obtenez une 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 dit que cela a échoué. Si vous avez un tableau numpy avec exactement un élément, l'instruction if "fonctionnera", dans le sens où vous n'obtiendrez pas d'erreur. Cependant, s'il se trouve que cet élément est 0 (ou 0.0 , ou false , ...), l'instruction if aboutira à tort à false :

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

Mais clairement x existe et n'est pas vide! Ce résultat n'est pas ce que tu voulais.

Utiliser 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 de scipy , la méthode correcte dans tous les cas où vous savez que vous avez un tableau numpy consiste à 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'une list , d'un tableau numpy ou autre, vous pouvez associer cette approche à 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 brisé la pythonicité au moins dans 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 de Numpy telles que 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 - principalement 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 le convertit au type choisi. Donc, c’est très rapide chaque fois que cela est possible, et cela vous permet de supposer que l’entrée est un tableau numpy. Nous utilisons généralement le même nom, car la conversion en tableau ne le fera pas revenir en dehors de la scope actuelle:

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

Cela fera fonctionner la vérification x.size dans tous les cas que je vois sur cette page.


La réponse de Patrick (acceptée) est la bonne: if not a: est la bonne façon de le faire. Harley Holcombe a raison de dire que cela figure dans le guide de rédaction du PEP 8. Mais ce qu’aucune des réponses n’explique, c’est pourquoi il est judicieux de suivre cet idiome, même si vous trouvez personnellement qu’il n’est pas assez explicite ou déroutant pour les utilisateurs de Ruby ou autre.

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

Il est vrai que if not a: ce if not a: ne distingue pas les listes vides de None , ni de 0 numérique, ni de nuplets vides, ni de types de collection vides créés par l'utilisateur, ni de types de collection vierges créés par l'utilisateur, ni de tableau NumPy à un seul élément agissant comme des scalaires avec des valeurs de Falsey, 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 rien en dehors d'une séquence est une erreur ici", etc. . En plus de rechercher exactement ce que vous souhaitez tester, cela indique également au lecteur que ce test est important.

Mais lorsque vous n’avez rien pour être explicite, rien d’autre que if not a: induit le lecteur en erreur. Vous signalez quelque chose d'aussi important quand ce n'est pas le cas. (Vous pouvez également rendre le code moins flexible, ou plus lent, mais c'est tout aussi important.) Et si vous induisez habituellement le lecteur en erreur, alors lorsque vous aurez besoin de faire une distinction, cela passera inaperçu car vous avez "crié au loup" partout dans votre code.


Si vous voulez vérifier si la liste est vide;

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

Si vous voulez vérifier la météo, toutes les valeurs de la liste sont vides.

if empty_list(lst):
    # do your stuff.

Cependant, cela sera vrai pour une liste vide.

print('not empty' if a else 'empty')

Maintenant vous pouvez utiliser:

a.pop() if a else None

Utilisez simplement is_empty () ou utilisez la fonction suivante: -

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

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


La valeur de vérité d'une liste vide est Falsealors que pour une liste non vide, c'est le cas True.


a == []

un peu plus pratique:

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

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 séparément None et séparément, 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

Bien que rien ne vaille que None soit de la fausseté Donc, si vous ne voulez pas séparer le test None , 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




is-empty