¿Cómo verifico si una lista está vacía?

3231

Por ejemplo, si pasa lo siguiente:

a = []

¿Cómo verifico si aestá vacío?

0
6462
if not a:
  print("List is empty")

Usar el valor booleano implícito del vacío listes bastante pitónico.

25
  • 1311
    Jugando al abogado del diablo. No entiendo por qué este idioma se considera pitónico. 'Explícito es mejor que implícito', ¿correcto? Esta comprobación no parece muy explícita sobre lo que se está comprobando. 22/11/11 a las 6:14
  • 250
    @JamesMcMahon: es un compromiso entre lo explícito y la flexibilidad de tipos. en general, "ser explícito" significa no hacer cosas "mágicas". por otro lado, "escribir pato" significa trabajar con interfaces más generales, en lugar de verificar explícitamente los tipos. entonces algo como if a == []forzar un tipo particular ( () == []es False). aquí, el consenso general parece ser que la escritura pato gana (de hecho, dice que __nonzero__es la interfaz para probar la vacuidad docs.python.org/reference/datamodel.html#object.__nonzero__ ) 31 de mayo de 12 a las 14:50
  • 77
    Este método no funciona en matrices numpy ... así que creo que si len (a) == 0 es preferible tanto en términos de "tipificación de pato" e implícitamente. 20/03/19 a las 18:01
  • 20
    La forma canónica de saber si una matriz en C está vacía es desreferenciar el primer elemento y ver si es nulo, asumiendo una matriz con terminación nula. De lo contrario, comparar su longitud con cero es completamente ineficaz si la matriz tiene un tamaño significativo. Además, normalmente, no asignaría memoria para una matriz vacía (el puntero permanece nulo), por lo que no tiene sentido intentar obtener su longitud. No estoy diciendo que len (a) == 0 no sea una buena forma de hacerlo, simplemente no me grita 'C' cuando la veo. 2/04/19 a las 23:55
  • 42
    Procedente de un lenguaje que pretende ser una especie de poesía, este mecanismo es pura basura. Semánticamente, estar vacío es muy diferente a no estar 4 abr.20 a las 14:03
1323

La forma pitónica de hacerlo es de la guía de estilo PEP 8 (donde significa "recomendado" y No significa "no recomendado"):

For sequences, (strings, lists, tuples), use the fact that empty sequences are false.

Yes: if not seq:
     if seq:

No:  if len(seq):
     if not len(seq):
9
  • 84
    La segunda forma parece mejor si desea señalar que seqse espera que sea algún tipo de objeto similar a una lista. 10 de mayo de 2018 a las 18:44
  • dieciséis
    @BallpointBen que, dirían los defensores del pitonismo, debería estar implícito en la forma en que se nombra la variable, tanto como sea posible
    axolotl
    14/07/18 a las 5:35
  • 11
    @BallpointBen intente usar la sugerencia de tipo de Python para señalar lo que debería ser una variable. Fue introducido en 3.5.
    Boris
    4 de enero de 2019 a las 23:46
  • 12
    numpy rompió este modismo ... seq = numpy.array ([1,2,3]) seguido de if not seq genera una excepción "ValueError: El valor de verdad de una matriz con más de un elemento es ambiguo. Use a.any () o a.todos () " 20/03/19 a las 18:03
  • 6
    A pesar de todos los defensores de Pythonic, estoy con @BallpointBen en el sentido de que si escribió erróneamente seq = [0]como seq = 0, len(seq)lo ayudará a detectar el error. Errar es humano. También lo es un programador.
    aafulei
    26 de septiembre de 2019 a las 2:34
920

Lo prefiero explícitamente:

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

De esta manera queda 100% claro que lies una secuencia (lista) y queremos probar su tamaño. Mi problema if not li: ...es que da la falsa impresión de que lies una variable booleana.

19
  • 117
    Verificar si la longitud de una lista es igual a cero, en lugar de simplemente verificar si la lista es falsa, es feo y poco pitónico. Cualquiera que esté familiarizado con Python no pensará que lies un bool en absoluto, y no le importará. Si es importante, debe agregar un comentario, no más código. 9 de julio de 2013 a las 13:43
  • 27
    Esto parece una prueba innecesariamente precisa, que a menudo es más lenta y siempre es menos legible en mi humilde opinión. En lugar de verificar el tamaño de algo vacío, ¿por qué no simplemente verificar si está vacío?
    John B
    23 jun 14 a las 14:46
  • 40
    De todos modos, la razón por la que esto es malo (y que violar modismos en un lenguaje con modismos fuertes como Python es malo en general) es que le indica al lector que está verificando específicamente la longitud por alguna razón (por ejemplo, porque quiere Noneo 0para plantear una excepción en lugar de pasar). Así que, cuando lo hace sin razón, eso es engañosa, y también significa que cuando el código hace necesario hacer la distinción, la distinción es invisible porque se ha "llorado lobo" por todo el resto de la fuente. 3 dic '14 a las 2:05
  • 25
    Creo que esto solo alarga innecesariamente el código. De lo contrario, ¿por qué no ser aún más "explícito" con if bool(len(li) == 0) is True:?
    augurar
    5 de ene. De 2015 a las 19:40
  • 13
    @Jabba será O (1) en muchos casos (aquellos en los que trabaja con los tipos de datos integrados), pero no puede confiar en eso. Es posible que esté trabajando con un tipo de datos personalizado que no tenga esta propiedad. También puede decidir agregar este tipo de datos personalizados más adelante, después de haber escrito este código.
    ralokt
    19/11/15 a las 13:04
369

Este es el primer acierto de Google para "Python test empty array" y consultas similares, además de que otras personas parecen estar generalizando la pregunta más allá de las listas, así que pensé en agregar una advertencia para un tipo diferente de secuencia que mucha gente Puede usar.

Otros métodos no funcionan para matrices NumPy

Debe tener cuidado con las matrices NumPy, porque otros métodos que funcionan bien para lists u otros contenedores estándar fallan para las matrices NumPy. Explico por qué a continuación, pero en resumen, el método preferido es usar size.

La forma "pitónica" no funciona: Parte 1

La forma "pitónica" falla con los arreglos NumPy porque NumPy intenta convertir el arreglo en un arreglo de bools, y if xtrata de evaluar todos esos bools a la vez para algún tipo de valor de verdad agregado. Pero esto no tiene ningún sentido, por lo que obtienes un 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 forma "pitónica" no funciona: Parte 2

Pero al menos el caso anterior te dice que falló. Si tiene una matriz NumPy con exactamente un elemento, la ifdeclaración "funcionará", en el sentido de que no obtendrá un error. Sin embargo, si ese elemento es 0(o 0.0, o False, ...), la ifdeclaración dará como resultado incorrectamente False:

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

¡Pero claramente xexiste y no está vacío! Este resultado no es el que querías.

El uso lenpuede dar resultados inesperados

Por ejemplo,

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

devuelve 1, aunque la matriz tenga cero elementos.

La forma numpythonic

Como se explica en las Preguntas frecuentes de SciPy , el método correcto en todos los casos en los que sabe que tiene una matriz NumPy es usar 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 no está seguro de si podría ser una listmatriz NumPy u otra cosa, puede combinar este enfoque con la respuesta que da @dubiousjim para asegurarse de que se use la prueba correcta para cada tipo. No es muy "pitónico", pero resulta que NumPy rompió intencionalmente la pitonicidad al menos en este sentido.

Si necesita hacer algo más que verificar si la entrada está vacía y está utilizando otras funciones de NumPy como indexación u operaciones matemáticas, probablemente sea más eficiente (y ciertamente más común) forzar la entrada a ser una matriz NumPy. Hay algunas funciones interesantes para hacer esto rápidamente, lo más importante numpy.asarray. Esto toma su entrada, no hace nada si ya es una matriz, o envuelve su entrada en una matriz si es una lista, tupla, etc., y opcionalmente la convierte a su elección dtype. Por lo tanto, es muy rápido siempre que puede ser, y garantiza que simplemente asuma que la entrada es una matriz NumPy. Por lo general, incluso usamos el mismo nombre, ya que la conversión a una matriz no saldrá del alcance actual :

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

Esto hará que el x.sizecheque funcione en todos los casos que veo en esta página.

16
  • 71
    Vale la pena señalar que esto no es un defecto en Python, sino más bien una ruptura intencional del contrato por numpy: numpyes una biblioteca con un caso de uso muy específico, y tiene una definición 'natural' diferente de lo que es la veracidad en una matriz para el Estándar de Python para contenedores. Tiene sentido optimizar para ese caso, de la forma que se pathlibusa /para concatenar rutas en lugar de +: no es estándar, pero tiene sentido en el contexto. 16 feb.15 a las 20:47
  • 10
    Acordado. Mi punto es solo que es importante recordar que numpy ha tomado la decisión de romper el tipeo de pato tanto para los más comunes if xcomo para los len(x)modismos, y a veces esa rotura puede ser muy difícil de detectar y depurar.
    Mike
    16 feb.15 a las 21:21
  • 24
    No sé, para mí, si un método llamado len (x) no devuelve la longitud de la matriz debido a suposiciones, su nombre está mal diseñado.
    Dalton
    20/08/15 a las 19:54
  • 12
    Esta pregunta no tiene nada que ver con matrices numpy
    pppery
    31/07/2017 a las 18:58
  • 25
    @ppperry Sí, la pregunta original no se refería a las matrices Numpy, pero cuando se trabaja con esos argumentos y posiblemente con el tipo pato, esta pregunta se vuelve muy relevante. 12 sep 2017 a las 21:22
286

Best way to check if a list is empty

For example, if passed the following:

a = []

How do I check to see if a is empty?

Respuesta corta:

Coloque la lista en un contexto booleano (por ejemplo, con una declaración ifo while). Probará Falsesi está vacío y de lo Truecontrario. Por ejemplo:

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

PEP 8

PEP 8 , la guía de estilo oficial de Python para el código Python en la biblioteca estándar de Python, afirma:

For sequences, (strings, lists, tuples), use the fact that empty sequences are false.

Yes: if not seq:
     if seq:

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

Deberíamos esperar que el código de biblioteca estándar sea lo más eficaz y correcto posible. Pero, ¿por qué es así y por qué necesitamos esta guía?

Explicación

Con frecuencia veo código como este de programadores experimentados nuevos en Python:

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

Y los usuarios de lenguajes perezosos pueden tener la tentación de hacer esto:

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

Estos son correctos en sus respectivos otros idiomas. Y esto es incluso semánticamente correcto en Python.

Pero lo consideramos no Pythonic porque Python admite esta semántica directamente en la interfaz del objeto de lista mediante coerción booleana.

De los documentos (y tenga en cuenta específicamente la inclusión de la lista vacía []):

By default, an object is considered true unless its class defines either a __bool__() method that returns False or a __len__() method that returns zero, when called with the object. Here are most of the built-in objects considered false:

  • constants defined to be false: None and False.
  • zero of any numeric type: 0, 0.0, 0j, Decimal(0), Fraction(0, 1)
  • empty sequences and collections: '', (), [], {}, set(), range(0)

Y la documentación del modelo de datos:

object.__bool__(self)

Called to implement truth value testing and the built-in operation bool(); should return False or True. When this method is not defined, __len__() is called, if it is defined, and the object is considered true if its result is nonzero. If a class defines neither __len__() nor __bool__(), all its instances are considered true.

y

object.__len__(self)

Called to implement the built-in function len(). Should return the length of the object, an integer >= 0. Also, an object that doesn’t define a __bool__() method and whose __len__() method returns zero is considered to be false in a Boolean context.

Entonces en lugar de esto:

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

o esto:

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

Hacer esto:

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

Hacer lo que Pythonic suele dar sus frutos en rendimiento:

¿Vale la pena? (Tenga en cuenta que menos tiempo para realizar una operación equivalente es mejor :)

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

Para escalar, aquí está el costo de llamar a la función y construir y devolver una lista vacía, que puede restar de los costos de las comprobaciones de vacío utilizadas anteriormente:

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

Vemos que sea la comprobación de longitud con la función incorporada lenen comparación con 0 o comprobación con una lista vacía es mucho menos eficiente que el uso de la sintaxis de la lengua incorporada como se documenta.

¿Por qué?

Para el len(a) == 0cheque:

Primero Python tiene que verificar los globales para ver si lenestá sombreado.

Luego debe llamar a la función, cargar 0y hacer la comparación de igualdad en Python (en lugar de con 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

Y para [] == []ello tiene que construir una lista innecesaria y luego, nuevamente, hacer la operación de comparación en la máquina virtual de Python (en contraposición a C)

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

La forma "Pythonic" es una verificación mucho más simple y rápida ya que la longitud de la lista se almacena en caché en el encabezado de la instancia del objeto:

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

Evidencia de la fuente C y documentación

PyVarObject

This is an extension of PyObject that adds the ob_size field. This is only used for objects that have some notion of length. This type does not often appear in the Python/C API. It corresponds to the fields defined by the expansion of the PyObject_VAR_HEAD macro.

De la fuente c en Incluir / 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

Respuesta a los comentarios:

I would point out that this is also true for the non-empty case though its pretty ugly as with l=[] then %timeit len(l) != 0 90.6 ns ± 8.3 ns, %timeit l != [] 55.6 ns ± 3.09, %timeit not not l 38.5 ns ± 0.372. But there is no way anyone is going to enjoy not not l despite triple the speed. It looks ridiculous. But the speed wins out
I suppose the problem is testing with timeit since just if l: is sufficient but surprisingly %timeit bool(l) yields 101 ns ± 2.64 ns. Interesting there is no way to coerce to bool without this penalty. %timeit l is useless since no conversion would occur.

La magia de IPython, %timeitno es del todo inútil aquí:

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)

Podemos ver que hay un poco de costo lineal por cada adicional notaquí. Queremos ver los costos, ceteris paribus , es decir, todo lo demás igual, donde todo lo demás se minimiza en la medida de lo posible:

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)

Ahora veamos el caso de una lista vacía:

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)

Lo que podemos ver aquí es que hay poca diferencia entre pasar una boolverificación de condición real a la condición o la lista misma y, en todo caso, dar la lista, tal como está, es más rápido.

Python está escrito en C; usa su lógica en el nivel C. Todo lo que escriba en Python será más lento. Y probablemente será órdenes de magnitud más lento a menos que esté utilizando los mecanismos integrados en Python directamente.

4
  • 1
    Me gustaría señalar que esto también es cierto para el caso de que no esté vacío, aunque es bastante feo como la l=[]continuación %timeit len(l) != 0de 90,6 ± 8,3 ns ns, %timeit l != []55,6 ns ± 3,09, %timeit not not l38,5 ns ± 0,372. Pero no hay forma de que nadie lo disfrute a not not lpesar de triplicar la velocidad. Parece ridículo. Pero la velocidad gana 28/11/19 a las 5:52
  • 1
    Supongo que el problema es probar con el tiempo, ya que solo if l:es suficiente pero sorprendentemente %timeit bool(l)arroja 101 ns ± 2.64 ns. Interesante, no hay forma de coaccionar a bool sin esta penalización. %timeit les inútil ya que no se produciría ninguna conversión. 28 nov 2019 a las 6:31
  • 4
    ¡La mejor respuesta hasta ahora, gracias! Señalar la verdadera lógica de Python con métodos mágicos y "Python está escrito en C; usa su lógica en el nivel C. Todo lo que escribas en Python será más lento. Y probablemente será órdenes de magnitud más lento" es la clave. de lo contrario, uno cae en "preferencias" y nunca llega a una conclusión adecuada. 17 nov.20 a las 15:39
  • 1
    ¡Excelente! ¡Esta es la mejor respuesta! Para cualquiera que lea desde 2020 (es diciembre, es casi 2021) y en el futuro. Hacerlo if les de la manera "Pythonic" y la MEJOR manera, ya que este tipo lo explica muy bien y también proporcionó un código de muestra del rendimiento de tiempo calculado para cada respuesta sugerida que son if len(a) == 0, if [] == [] y if aclaramente esto ( if a) es mucho más rápido y el que debe ser practicado! 19/12/20 a las 15:22
157

Una lista vacía en sí misma se considera falsa en las pruebas de valor verdadero (consulte la documentación de Python ):

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

@Daren Thomas

EDIT: Another point against testing the empty list as False: What about polymorphism? You shouldn't depend on a list being a list. It should just quack like a duck - how are you going to get your duckCollection to quack ''False'' when it has no elements?

Su duckCollection debería implementar __nonzero__o __len__así el if a: funcionará sin problemas.

2
  • Extraño, ¿cómo [] == Falsese evaluará a Falso? 14/10/19 a las 3:34
  • 3
    @information_interchange Si desea verificar explícitamente la veracidad de un valor, use bool(). bool([]) == Falseevaluará Truecomo se esperaba.
    augurar
    20/10/19 a las 7:29
111

La respuesta (aceptada) de Patrick es correcta: if not a:es la forma correcta de hacerlo. La respuesta de Harley Holcombe es correcta: está en la guía de estilo de PEP 8. Pero lo que ninguna de las respuestas explica es por qué es una buena idea seguir el idioma, incluso si personalmente encuentra que no es lo suficientemente explícito o confuso para los usuarios de Ruby o lo que sea.

El código Python y la comunidad de Python tienen modismos muy fuertes. Seguir esos modismos hace que su código sea más fácil de leer para cualquier persona con experiencia en Python. Y cuando violas esos modismos, es una señal fuerte.

Es cierto que if not a:no distingue las listas vacías None, ni el 0 numérico, ni las tuplas vacías, ni los tipos de colección vacíos creados por el usuario, ni los tipos de colección no del todo vacíos creados por el usuario, o la matriz NumPy de un solo elemento que actúa como escalares con falsey valores, etc. Y a veces es importante ser explícito al respecto. Y en ese caso, usted sabe sobre qué quiere ser explícito, por lo que puede probar exactamente eso. Por ejemplo, if not a and a is not None:significa "cualquier error excepto Ninguno", mientras que if len(a) != 0:significa "sólo secuencias vacías, y cualquier cosa que no sea una secuencia es un error aquí", y así sucesivamente. Además de probar exactamente lo que desea probar, esto también le indica al lector que esta prueba es importante.

Pero cuando no tienes nada sobre lo que ser explícito, cualquier otra cosa que no if not a:sea ​​engaña al lector. Estás señalando algo tan importante cuando no lo es. (Es posible que también estará haciendo el código menos flexible, o más lento, o lo que sea, pero eso es todo menos importante.) Y si habitualmente inducir a error al lector de este tipo, a continuación, cuando se hace necesario hacer una distinción, que va a pasar, porque desapercibido has estado "llorando lobo" en todo tu código.

1
  • 1
    "Y cuando violas esos modismos, es una señal fuerte". Puede ser una señal fuerte de que simplemente está trabajando con código escrito por alguien nuevo en Python, que es mucha gente
    joel
    17/06/20 a las 12:19
88

¿Por qué comprobarlo?

Nadie parece haber cuestionado su necesidad de probar la lista en primer lugar. Debido a que no proporcionó contexto adicional, puedo imaginar que es posible que no necesite hacer esta verificación en primer lugar, pero no esté familiarizado con el procesamiento de listas en Python.

Yo diría que la forma más pitónica es no verificar en absoluto, sino simplemente procesar la lista. De esa manera, hará lo correcto, ya sea vacío o lleno.

a = []

for item in a:
    <do something with item>

<rest of code>

Esto tiene la ventaja de manejar cualquier contenido de un , sin requerir una verificación específica de vacío. Si a está vacío, el bloque dependiente no se ejecutará y el intérprete pasará a la siguiente línea.

Si realmente necesita verificar si la matriz está vacía, las otras respuestas son suficientes.

7
  • 5
    La cuestión es que comprobar si la lista está vacía es bastante importante, al menos para mí. ¿Ha considerado si hay algún script dentro <rest of code>que pueda usar el resultado del forciclo? ¿O usar directamente algunos valores en a? De hecho, si el script está diseñado para ejecutarse con una entrada estrictamente controlada, la verificación puede ser un poco innecesaria. Pero en la mayoría de los casos, la entrada varía y, por lo general, es mejor tener una verificación. 2 feb 2018 a las 14:02
  • Respetuosamente, no. Lo que consideré fue alguien que no sabía lo suficiente sobre Python para saber que "if <list>:" era la respuesta correcta, preguntó cómo buscar una lista vacía. Luego noté MUCHAS respuestas que ofrecían opiniones diferentes, pero ninguna parecía abordar la necesidad original. Eso es lo que traté de hacer con mi respuesta: que examinen la necesidad antes de continuar. Creo que sugerí tanto en mi respuesta, explícitamente. 17/02/18 a las 19:18
  • @ AmarthGûl - ¿Cómo se pueden obtener los resultados del bucle for en el script dentro de <resto del código> para ser procesados? ¿En una lista, quizás? ¿O tal vez un dict? Si es así, se aplica la misma lógica. No entiendo cómo la entrada variable podría tener algún efecto dentro de cualquier tipo de código diseñado razonablemente, donde procesar una lista vacía sería una mala idea. 22 de mayo de 2018 a las 22:45
  • 1
    No, ha creado un problema O (n) en un cheque. solo estás considerando un buen resultado en una lista vacía. La respuesta funciona pero en mi opinión es subóptima
    DJK
    26/06/19 a las 2:21
  • 9
    @DJK - No, creo que todavía te lo estás perdiendo. Es de suponer que desea HACER algo con una lista, si tiene una. ¿Qué harías diferente si estuviera vacío? ¿Regresar temprano? ¿Y si no está vacío? ¿procesalo? Aún así, el punto es que probablemente no necesite buscar una lista vacía, simplemente repita sobre ella y haga lo que sea que vaya a hacer con los elementos. Si no hay elementos, fracasas. Si hay elementos, los procesa según sea necesario. El punto NO es usar el ejemplo PARA una verificación vacía, sino NO verificar en absoluto, solo procesar la lista. 27/06/19 a las 4:07
71

len()es una operación O (1) para listas, cadenas, dictados y conjuntos de Python. Python realiza un seguimiento interno de la cantidad de elementos en estos contenedores.

JavaScript tiene una noción similar de veracidad / falsedad .

0
48

He escrito:

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

que fue votado -1. No estoy seguro si eso se debe a que los lectores se opusieron a la estrategia o pensaron que la respuesta no era útil tal como se presentó. Pretenderé que fue lo último, ya que --- lo que sea que cuente como "pitónico" --- esta es la estrategia correcta. A menos que ya lo haya descartado, o esté preparado para manejar casos en los aque, por ejemplo, Falsenecesite una prueba más restrictiva que simplemente if not a:. Podrías usar algo como esto:

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

la primera prueba es en respuesta a la respuesta de @ Mike, arriba. La tercera línea también podría reemplazarse con:

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

si solo desea aceptar instancias de tipos particulares (y sus subtipos), o con:

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

Puede salirse sin la verificación de tipo explícita, pero solo si el contexto circundante ya le asegura que aes un valor de los tipos que está preparado para manejar, o si está seguro de que los tipos que no está preparado para manejar van a funcionar. para generar errores (por ejemplo, a TypeErrorsi invoca lenun valor para el que no está definido) que está preparado para manejar. En general, las convenciones "pitónicas" parecen ir por este último camino. Apriétalo como un pato y déjalo generar un DuckError si no sabe graznar. Sin embargo, todavía tiene que pensar en qué tipo de suposiciones está haciendo y si los casos que no está preparado para manejar correctamente realmente van a fallar en los lugares correctos. Las matrices Numpy son un buen ejemplo en el que confiar ciegamente enlen o el encasillado booleano puede no hacer precisamente lo que esperas.

7
  • 3
    Es bastante raro que tenga una lista exhaustiva de 6 tipos que desee aceptar y no sea flexible para otros tipos. Cuando necesite ese tipo de cosas, probablemente desee un abecedario. En este caso, probablemente sería uno de los ABC de stdlib, como collections.abc.Sizedo collections.abc.Sequence, pero podría ser uno que escriba usted mismo register(list). Si realmente tiene un código en el que es importante distinguir el vacío de otros falsey, y también para distinguir listas y tuplas de cualquier otra secuencia, entonces esto es correcto, pero no creo que tenga ese código. 3 de diciembre de 2014 a las 2:09
  • 13
    La razón por la que a la gente no le gusta esto es porque en la mayoría de los casos es completamente inadmisible. Python es un lenguaje de tipo pato, y este nivel de codificación defensiva lo obstaculiza activamente. La idea detrás del sistema de tipos de Python es que las cosas deberían funcionar siempre que el objeto pase las funciones de la manera que necesita. Al realizar comprobaciones de tipo explícitas, está obligando a la persona que llama a utilizar tipos específicos, yendo en contra de la esencia del lenguaje. Si bien en ocasiones tales cosas son necesarias (excluyendo cadenas de ser tratadas como secuencias), tales casos son raros y casi siempre mejores como listas negras. 16/02/15 a las 20:54
  • 1
    Si realmente desea verificar que el valor es exactamente []y no algo falso de otro tipo, entonces seguramente if a == []:es necesario, en lugar de jugar con isinstance. 16/07/2015 a las 13:10
  • 2
    Sin ==embargo, existen algunas coacciones automáticas . En la parte superior de mi cabeza, no puedo identificar a ninguno []. [] == ()por ejemplo regresa False. Pero, por ejemplo, frozenset()==set()vuelve True. Por lo tanto, vale la pena pensar al menos si algún tipo no deseado podría ser coaccionado [](o viceversa) al hacerlo a == []. 16/07/2015 a las 13:36
  • @RemcoGerlich - isinstance () sigue siendo preferible en lugar de construir una lista vacía para comparar. Además, como señaló otro, el operador de igualdad puede invocar la conversión implícita de algunos tipos, lo que puede ser indeseable. No hay ninguna razón para codificar "a == []" y ese código definitivamente se marcaría como un defecto en cualquier revisión de código en la que haya participado. El uso de la herramienta adecuada según lo provisto por el lenguaje no debe considerarse "tonterías , "sino más bien" una buena técnica de programación ". 12 oct 2018 a las 4:47
35

De la documentación sobre las pruebas de valor de verdad:

Todos los valores distintos de los que se enumeran aquí se consideran True

  • None
  • False
  • cero de cualquier tipo numérico, por ejemplo, 0, 0.0, 0j.
  • cualquier secuencia de vacío, por ejemplo, '', (), [].
  • cualquier mapeo vacío, por ejemplo {},.
  • instancias de clases definidas por el usuario, si la clase define un método __bool__()o __len__(), cuando ese método devuelve el valor entero cero o bool False.

Como se puede ver, la lista vacía []es falsa , por lo que hacer lo que se haría con un valor booleano suena más eficiente:

if not a:
    print('"a" is empty!')
1
  • @DJ_Stuffy_K afirmar qué en las pruebas unitarias, ¿una lista vacía? Solo usa assert(not myList). Si también desea afirmar que el objeto es a list, puede usar assertIsInstance(). 1 de septiembre de 2018 a las 5:39
33

Prefiero lo siguiente:

if a == []:
   print "The list is empty."
5
  • 45
    Esto va a ser más lento, ya que crea una instancia de una lista vacía adicional innecesariamente. 10 de septiembre de 2008 a las 13:42
  • 39
    esto es menos legible if not a:y se rompe más fácilmente. Por favor, no lo hagas.
    devsnd
    12/11/12 a las 11:23
  • Hay un buen punto hecho antes () == []que también es igual a falso. Aunque me gusta cómo esta implementación lee if not a:todos los casos, si definitivamente está esperando una lista, su ejemplo debería ser suficiente.
    A Star
    16/03/19 a las 21:03
  • 3
    "se rompe más fácilmente" ¿se necesita una cita? if not ase rompe cuando a es None: es posible que desee el mismo comportamiento para Noney [], pero si desea verificar explícitamente una lista vacía, if not ano lo haga.
    scubbo
    20/08/20 a las 16:14
  • @scubbo si realmente desea verificar explícitamente si es una lista vacía o no, considere usar en su isinstance(a, list) and not alugar.
    AboodXD
    22 de abril a las 10:59
31

A continuación, se muestran algunas formas en las que puede verificar si una lista está vacía:

a = [] #the list

1) La forma pitónica bastante simple:

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

En Python, los contenedores vacíos como listas, tuplas, conjuntos, dictados, variables, etc. se ven como False. Uno podría simplemente tratar la lista como un predicado ( devolviendo un valor booleano ). Y un Truevalor indicaría que no está vacío.

2) Una forma mucho más explícita: usar len()para encontrar la longitud y verificar si es igual a 0:

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

3) O comparándolo con una lista vacía anónima:

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

4) Otra forma tonta de hacerlo es usar exceptiony iter():

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

Método 1 (preferido):

if not a : 
   print ("Empty") 

Método 2:

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

Método 3:

if a == [] :
  print ("Empty")
0
22

Incluso puedes intentar usarlo bool()así. Aunque es menos legible, seguramente es una forma concisa de realizar esto.

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

Me encanta esta forma porque la lista de verificación está vacía o no.

Muy práctico y útil.

3
  • 6
    Para aquellos (como yo) que no lo sabían, bool()convierte una variable de Python en un booleano para que pueda almacenar la veracidad o falsedad de un valor sin tener que usar una declaración if. Creo que es menos legible que simplemente usar un condicional como la respuesta aceptada, pero estoy seguro de que hay otros buenos casos de uso para ello. 10/03/2017 a las 21:42
  • Esto se puede utilizar en una expresión y es más conciso.
    qneill
    18 dic 2017 a las 21:13
  • 1
    La desventaja ocurre cuando a is None. Esto suele ser aceptable, pero es bueno tenerlo en cuenta.
    Lars P
    29/09/20 a las 19:26
17
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])

A veces es bueno probar la Nonevacuidad y la vacuidad por separado, ya que son dos estados diferentes. El código anterior produce el siguiente resultado:

list is None 
list is empty 
list has 3 elements

Aunque no vale nada que Nonesea ​​falso. Entonces, si no desea separar la prueba de la Nonecondición, no tiene que hacer eso.

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

produce esperado

list is empty
list is empty
list has 3 elements
1
  • 1
    En mi humilde opinión, esta es la mejor respuesta. Aborda los matices con respecto a Noney [](una lista vacía) al realizar la prueba. 24 nov.20 a las 15:59
13

Se han dado muchas respuestas y muchas de ellas son bastante buenas. Solo quería agregar que el cheque

not a

también pasará por Noney otros tipos de estructuras vacías. Si realmente desea verificar si hay una lista vacía, puede hacer esto:

if isinstance(a, list) and len(a)==0:
    print("Received an empty list")
2
  • Es posible que esto arroje una excepción, si ano es una lista y ano tiene un método __len__implementado. Yo recomendaria:if isinstance(obj, list): if len(obj) == 0: print '...' 10 de ene. De 2019 a las 9:40
  • 6
    @ SvenKrüger no. El operador andes vago en Python. No andse ejecutará nada después si la condición anterior andes Falsa. 26 feb 2019 a las 14:00
13

Si desea comprobar si una lista está vacía:

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

Si desea comprobar si todos los valores de la lista están vacíos. Sin embargo, será Truepara una lista vacía:

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

Si desea usar ambos casos juntos:

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

Ahora puedes usar:

if empty_list(lst):
    # do your stuff.
1
  • 1
    all (bool (x) para x en l) es verdadero para una lista vacía
    gberger
    5 mar 18 a las 17:27
11

To check whether a list is empty or not you can use two following ways. But remember, we should avoid the way of explicitly checking for a type of sequence (it's a less pythonic way):

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

The second way is a more pythonic one. This method is an implicit way of checking and much more preferable than the previous one.

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"

Espero que esto ayude.

2
  • ¡Votado también por mostrar cómo verificar si no está vacío! Esto ayuda a cubrir el caso de uso opuesto pero igualmente importante 16/08/20 a las 17:01
  • 1
    Tenga en cuenta que el segundo puede no funcionar con otros objetos de tipo de matriz común, como matrices numpy. 2 de febrero a las 11:11
10

Inspirándome en la solución de @dubiousjim, propongo usar una verificación general adicional de si es algo iterable

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

Nota: una cadena se considera iterable. - agregue and not isinstance(a,(str,unicode))si desea que se excluya la cadena vacía

Prueba:

>>> 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
2
  • 2
    Overbroad; esto es solo preguntar si una lista está vacía, no si algo es un iterable vacío.
    pppery
    12/07/2017 a las 15:47
  • 1
    Si no estuviera contento if a:, sería porque quería una excepción si ano fuera algún tipo de contenedor. (Ser un iterable también permite iteradores, que no pueden probarse de manera útil para determinar la vacuidad). 20 de septiembre de 2017 a las 2:40
10

podríamos usar un simple if else:

item_list=[]
if len(item_list) == 0:
    print("list is empty")
else:
    print("list is not empty")
1
  • 5
    -1 - Para evitar confusiones, no use palabras reservadas para los nombres de variables o puede obtener un comportamiento sorprendente la próxima vez que intente llamar, por ejemplo, "list ()" ... algo como "TypeError: 'list' object is no invocable "o algo así. 29/04/19 a las 9:08
9
print('not empty' if a else 'empty')

un poco más práctico:

a.pop() if a else None

y versión más pura:

if a: a.pop() 
7

Simplemente use is_empty () o haga una función como: -

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

Se puede utilizar para cualquier estructura de datos como una lista, tuplas, diccionario y muchos más. Por estos, puede llamarlo muchas veces usando solo is_empty(any_structure).

3
  • 3
    El nombre is_emptysugiere que devuelve algo. Pero si lo hiciera, ese algo simplemente sería bool(any_structure), que debería usar en su lugar ( cuando lo necesite bool). 20 de septiembre de 2017 a las 2:39
  • 4
    ¿Por qué queremos una variación de boolque (también) imprima mensajes en la salida estándar? 20 de septiembre de 2017 a las 3:13
  • @DavisHerring Siempre tenemos dos opciones, la primera es imprimir usando la función, la otra es usar la boolvariable de retorno . La elección es tuya. Escribo ambos para que puedas elegir entre ellos. 20 de septiembre de 2017 a las 3:45
7

Una forma simple es verificar que la longitud sea igual a cero.

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

Desde python3 en adelante, puede usar

a == []

para comprobar si la lista está vacía

EDITAR: Esto también funciona con python2.7.

No estoy seguro de por qué hay tantas respuestas complicadas. Es bastante claro y sencillo

5
  • 2
    por favor, dé más explicaciones sobre cómo está funcionando sin escribir "si". 30/12/18 a las 10:48
  • 4
    Esto no es pitónico ni un ejemplo completo. Además, crea una instancia de una lista vacía cada vez que se encuentra. No hagas esto. 29/04/19 a las 8:53
  • 1
    @MrWonderful no crea una instancia de una lista vacía cada vez. Simplemente verifica si la lista existente aestá vacía o no.
    Trect
    6 abr.20 a las 15:44
  • 1
    @MrWonderful, no entiendo lo que lo hace pythonic
    Trect
    6 abr.20 a las 15:45
  • 1
    @ganeshdeshmukh si lo usa a==[]se imprimirá verdadero en la terminal de Python si está vacío. De lo contrario, se imprimirá Falso. Puede usar esto dentro de una condición if también comoif(a==[])
    Trect
    6 abr.20 a las 15:47
5

El valor de verdad de una lista vacía es Falsemientras que para una lista no vacía lo es True.

4

Lo que me trajo aquí es un caso de uso especial: en realidad quería una función que me dijera si una lista está vacía o no. Quería evitar escribir mi propia función o usar una expresión lambda aquí (porque parecía que debería ser lo suficientemente simple):

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

Y, por supuesto, hay una forma muy natural de hacerlo:

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

Por supuesto, no lo use boolen if(es decir, if bool(L):) porque está implícito. Pero, para los casos en los que "no está vacío" se necesita explícitamente como función, booles la mejor opción.