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

3234

Por ejemplo, si se pasa lo siguiente:

a = []

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

Rayo
fuente

Respuestas:

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

Usar la booleanidad implícita del vacío listes bastante pitónico.

Patricio
fuente
1130
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.
James McMahon
222
@JamesMcMahon: es una compensación 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 == []está forzando un tipo particular ( () == []es False). aquí, el consenso general parece ser que el tipeo de pato gana (en efecto, dice que esa __nonzero__es la interfaz para probar el vacío docs.python.org/reference/datamodel.html#object.__nonzero__ )
andrew cooke
38
Este método no funciona en matrices numpy ... así que creo que si len (a) == 0 es preferible tanto en términos de "tipeo de pato" como implícito.
Mr.WorshipMe
10
La forma canónica de saber si una matriz en C está vacía es haciendo referencia al primer elemento y ver si es nulo, suponiendo que una matriz está terminada en nulo. De lo contrario, comparar su longitud con cero es completamente ineficiente si la matriz es de un tamaño significativo. Además, por lo general, no asignaría memoria para una matriz vacía (el puntero sigue siendo nulo), por lo que no tiene sentido intentar obtener su longitud. No estoy diciendo que len (a) == 0 no sea una buena manera de hacerlo, simplemente no me grita 'C' cuando lo veo.
sleblanc
66
@BrennenSprimont, si no tiene terminación nula, entonces ya sabe la longitud, si está almacenada en una variable separada o si su matriz está envuelta en un contenedor que rastrea la longitud. C ++, Java, C # tienen dichos contenedores e implementan algún método de "longitud" de manera eficiente. C no tiene tal cosa , tienes que rodar la tuya. Las matrices C asignadas estáticamente son solo punteros a un espacio de memoria que garantiza tener suficiente espacio para almacenar la cantidad de datos que ha solicitado. No hay nada integrado en C que le permita saber cuánto ha llenado ese espacio ya.
sleblanc
1160

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

Para secuencias (cadenas, listas, tuplas), use el hecho de que las secuencias vacías son falsas.

Yes: if not seq:
     if seq:

No:  if len(seq):
     if not len(seq):
Harley Holcombe
fuente
49
La segunda forma parece mejor si desea indicar que seqse espera que sea algún tipo de objeto similar a una lista.
BallpointBen
55
@BallpointBen que, según los defensores del pitonismo, debería estar implícito en la forma en que se nombra la variable, tanto como sea posible
axolotl
99
@BallpointBen intente utilizar las sugerencias de tipo de Python para indicar qué debería ser una variable. Fue introducido en 3.5.
Boris
8
numpy rompió este idioma ... seq = numpy.array ([1,2,3]) seguido de si no seq genera una excepción "ValueError: el valor de verdad de una matriz con más de un elemento es ambiguo. Utilice a.any () o a.all () "
Mr.WorshipMe
2
@jeronimo: Creo que es una advertencia específica de lxml.
Harley Holcombe
769

Lo prefiero explícitamente:

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

De esta manera, es 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.

Jabba
fuente
9191
Verificar si la longitud de una lista es igual a cero, en lugar de solo verificar si la lista es falsa, es feo y antipático. 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.
Carl Smith
21
Esto parece una prueba innecesariamente precisa, que a menudo es más lenta y siempre es menos legible. En lugar de verificar el tamaño de algo vacío, ¿por qué no simplemente verificar si está vacío?
John B
34
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.
abarnert
18
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
11
@Jabba será O (1) en muchos casos (aquellos en los que trabaja con los tipos de datos integrados), pero simplemente no puede confiar en eso. Es posible que esté trabajando con un tipo de datos personalizado que no tiene esta propiedad. También puede decidir agregar este tipo de datos personalizado más tarde, después de que ya haya escrito este código.
ralokt
325

Este es el primer hit de Google para "matriz vacía de prueba de Python" y consultas similares, además de que otras personas parecen estar generalizando la pregunta más allá de las listas, por lo 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 listotros 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 las matrices NumPy porque NumPy intenta convertir la matriz en una matriz de bools, y if xtrata de evaluar todas esas bools a la vez en busca de 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 ifinstrucción "funcionará", en el sentido de que no obtiene un error. Sin embargo, si ese elemento resulta ser 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 xexiste claramente y no está vacío! Este resultado no es lo que querías.

Usar lenpuede dar resultados inesperados

Por ejemplo,

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

devuelve 1, aunque la matriz tiene cero elementos.

El camino 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, podría combinar este enfoque con la respuesta que @dubiousjim da para asegurarse de que se utiliza 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 más que simplemente verificar si la entrada está vacía, y está utilizando otras características de NumPy como operaciones de indexación o matemáticas, probablemente sea más eficiente (y ciertamente más común) forzar la entrada para que sea una matriz NumPy. Hay algunas buenas funciones 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 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 lo hará fuera 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.

Miguel
fuente
6262
Vale la pena señalar que esto no es una falla en Python, sino más bien una ruptura intencional del contrato numpy: numpyes una biblioteca con un caso de uso muy específico, y tiene una definición 'natural' diferente de lo que la verdad en una matriz es para el Python estándar para contenedores. Tiene sentido optimizar para ese caso, de la forma en que se pathlibutilizan /para concatenar rutas en lugar de +: no es estándar, pero tiene sentido en contexto.
Gareth Latty
99
Convenido. Lo que quiero decir es que es importante recordar que numpy ha tomado la decisión de romper el tipeo de patos tanto para los muy comunes if xcomo para los len(x)modismos, y a veces esa rotura puede ser muy difícil de detectar y depurar.
Mike
22
No sé, para mí, si un método llamado len (x) no devuelve la longitud de la matriz porque los supuestos, su nombre está mal diseñado.
Dalton
11
Esta pregunta no tiene nada que ver con matrices
numpy
19
@ppperry Sí, la pregunta original no era acerca de las matrices de Numpy, pero cuando se trabaja con esos y posiblemente argumentos mecanografiados, esta pregunta se vuelve muy relevante.
Peter
223

La mejor manera de verificar si una lista está vacía

Por ejemplo, si se pasa lo siguiente:

a = []

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

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:

Para secuencias (cadenas, listas, tuplas), use el hecho de que las secuencias vacías son falsas.

Yes: if not seq:
     if seq:

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

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

Explicación

Frecuentemente 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 verse tentados a hacer esto:

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

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

Pero consideramos que no es Pythonic porque Python admite esta semántica directamente en la interfaz del objeto de lista a través de la coerción booleana.

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

Por defecto, un objeto se considera verdadero a menos que su clase defina un __bool__()método que devuelve Falseo un __len__()método que devuelve cero, cuando se llama con el objeto. Aquí están la mayoría de los objetos incorporados considerados falsos:

  • constantes definidas como falsas: Noney False.
  • cero de cualquier tipo numérico: 0, 0.0, 0j, Decimal(0),Fraction(0, 1)
  • secuencias vacías y colecciones: '', (), [], {}, set(),range(0)

Y la documentación del modelo de datos:

object.__bool__(self)

Llamado a implementar pruebas de valor de verdad y la operación incorporada bool(); debería regresar Falseo True. Cuando este método no está definido, __len__()se llama, si está definido, y el objeto se considera verdadero si su resultado es distinto de cero. Si una clase no define ni __len__() ni __bool__(), todas sus instancias se consideran verdaderas.

y

object.__len__(self)

Llamado para implementar la función incorporada len(). Debería devolver la longitud del objeto, un entero> = 0. Además, un objeto que no define un __bool__()método y cuyo __len__()método devuelve cero se considera falso en un contexto booleano.

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 es Pythonic generalmente vale la pena 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 la escala, 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 hacerlo 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 [] == []eso tiene que construir una lista innecesaria y luego, nuevamente, hacer la operación de comparación en la máquina virtual de Python (en lugar de 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

Esta es una extensión de PyObjectque agrega el ob_sizecampo. Esto solo se usa para objetos que tienen alguna noción de longitud. Este tipo no suele aparecer en la API de Python / C. Corresponde a los campos definidos por la expansión de la PyObject_VAR_HEADmacro.

Desde la fuente c en 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

Respuesta a comentarios:

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 alguien disfrute a not not lpesar de triplicar la velocidad. Se ve ridículo. Pero la velocidad gana,
supongo que el problema se está probando con tiempo, ya que if l:es suficiente pero sorprendentemente %timeit bool(l)produce 101 ns ± 2.64 ns. Interesante no hay forma de obligar a bool sin esta penalización. %timeit les inútil ya que no ocurriría ninguna conversión.

La magia de IPython, %timeitno es completamente 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 hace poca diferencia si pasa una boolverificación real a la condición o la lista en sí, y en todo caso, dar la lista, como es, es más rápido.

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

Aaron Hall
fuente
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 alguien disfrute a not not lpesar de triplicar la velocidad. Se ve ridículo. Pero la velocidad gana
Gregory Morse
Supongo que el problema está probando con timeit ya que if l:es suficiente pero sorprendentemente %timeit bool(l)produce 101 ns ± 2.64 ns. Interesante no hay forma de obligar a bool sin esta penalización. %timeit les inútil ya que no ocurriría ninguna conversión.
Gregory Morse
139

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

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

@Daren Thomas

EDITAR: Otro punto en contra de probar la lista vacía como Falso: ¿Qué pasa con el polimorfismo? No debe depender de que una lista sea una lista. Simplemente debería graznar como un pato: ¿cómo vas a hacer que tu patoCollection grazne '' Falso '' cuando no tiene elementos?

Su duckCollection debería implementarse __nonzero__o __len__si if a: funcionará sin problemas.

Peter Hoffmann
fuente
Es extraño cómo [] == Falseevaluará a pesar Falso
information_interchange
@information_interchange Si desea verificar explícitamente la veracidad de un valor, use bool(). bool([]) == Falseevaluará a Truelo esperado.
augurar
103

La respuesta (aceptada) de Patrick es correcta: if not a:es la forma correcta de hacerlo. La respuesta de Harley Holcombe es correcta: esto está en la guía de estilo PEP 8. Pero lo que ninguna de las respuestas explica es por qué es una buena idea seguir el modismo, 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 de 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 de None, o el 0 numérico, o las tuplas vacías, o los tipos de colección vacíos creados por el usuario, o los tipos vacíos creados por el usuario que no son del todo colección, o la matriz NumPy de elemento único que actúa como escalares con falsey valores, etc. Y a veces es importante ser explícito al respecto. Y en ese caso, sabes de qué quieres ser explícito, por lo que puedes probar exactamente eso. Por ejemplo, if not a and a is not None:significa "cualquier cosa falsey excepto Ninguno", mientras que if len(a) != 0:significa "solo secuencias vacías, y cualquier cosa además de 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 para ser explícito, cualquier otra cosa que no if not a:sea ​​engañosa para el 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.

abarnert
fuente
78

¿Por qué verificar en absoluto?

Nadie parece haber abordado cuestionar su necesidad de probar la lista en primer lugar. Debido a que no proporcionó ningún contexto adicional, me imagino que, en primer lugar, es posible que no necesite hacer esta verificación, 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 el beneficio 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 la matriz para el vacío, las otras respuestas son suficientes.

Sr. Maravilloso
fuente
3
La cuestión es que verificar si la lista está vacía es bastante importante, al menos para mí. ¿Has considerado si hay algún script dentro <rest of code>que pueda usar el resultado del forbucle? ¿O directamente usar algunos valores en a? De hecho, si el script está diseñado para ejecutarse con una entrada estrictamente controlada, la verificación podría ser un poco innecesaria. Pero en la mayoría de los casos, la entrada varía, y tener un control suele ser mejor.
Amarth Gûl
Respetuosamente no. Lo que consideré fue que alguien que no sabía lo suficiente sobre Python como para saber que "if <list>:" era la respuesta correcta, me preguntó cómo buscar una lista vacía. Entonces noté MUCHAS respuestas que ofrecían opiniones diferentes, pero ninguna parecía abordar la necesidad original. Eso es lo que intenté hacer con mi respuesta: que examinen la necesidad antes de continuar. Creo que sugerí tanto en mi respuesta, explícitamente.
MrWonderful
@ AmarthGûl - ¿Cómo podría uno obtener los resultados del bucle for al script dentro del <resto del código> para ser procesado? ¿En una lista, tal vez? 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 razonablemente diseñado, donde procesar una lista vacía sería una mala idea.
MrWonderful
Un poco viejo, pero si solo estaba verificando si la lista estaba vacía, para una lista no vacía, su código repite el proceso una y otra vez cuando OP simplemente está buscando una operación de verificación. Solo imagine un peor escenario para ese código cuando n se acerca al infinito ...
DJK
77
@DJK - No, creo que todavía te lo estás perdiendo. Presumiblemente quieres HACER algo con una lista, si tienes una. ¿Qué harías diferente si estuviera vacío? ¿Regresar temprano? ¿Qué pasa si no está vacío? ¿procesalo? El punto es, aún así, que probablemente no necesite verificar una lista vacía, simplemente repita sobre ella y haga lo que fuera que hiciera con los elementos. Si no hay elementos, fallas. Si hay elementos, los procesa según lo necesite. El punto NO es usar el ejemplo PARA una verificación vacía, sino NO verificar en absoluto, solo procese la lista.
MrWonderful
40

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 fue útil como se presentó. Voy a fingir que fue lo último, ya que --- lo que cuenta como "pitónico" --- esta es la estrategia correcta. A menos que ya haya descartado o esté preparado para manejar casos en los aque, por ejemplo, Falsenecesita 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 escapar sin la verificación explícita de tipos, pero solo si el contexto circundante ya le asegura que ese 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 para generar errores (p. ej., TypeErrorsi llama lena un valor para el que no está definido) que está preparado para manejar. En general, las convenciones "pitónicas" parecen ir de esta última manera. Exprímalo como un pato y déjalo levantar un DuckError si no sabe graznar. Sin embargo, todavía tiene que pensar qué tipo de suposiciones está haciendo y si los casos que no está preparado para manejar adecuadamente realmente se equivocarán en los lugares correctos. Las matrices de Numpy son un buen ejemplo en el que solo confían ciegamente enlen o el tipo de letra booleano puede no hacer exactamente lo que espera.

dubiousjim
fuente
3
Es bastante raro que tenga una lista exhaustiva de 6 tipos que desea aceptar y que no sea flexible para ningún otro tipo. Cuando necesitas ese tipo de cosas, probablemente quieras un ABC. En este caso, probablemente sería uno de los stdlib ABC, como collections.abc.Sizedo collections.abc.Sequence, pero podría ser uno en el que usted mismo escriba register(list). Si realmente tiene un código en el que es importante distinguir los vacíos de otros falsey, y también distinguir las listas y tuplas de cualquier otra secuencia, entonces esto es correcto, pero no creo que tenga ese código.
abarnert
13
La razón por la que a la gente no le gusta esto es porque es totalmente inestable en la mayoría de los casos. 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 en funciones de la manera que necesita. Al hacer comprobaciones de tipo explícitas, está obligando a la persona que llama a usar tipos específicos, yendo en contra de la propia lengua. Si bien ocasionalmente tales cosas son necesarias (excluyendo que las cadenas sean tratadas como secuencias), tales casos son raros y casi siempre son mejores como listas negras.
Gareth Latty
1
Si realmente desea verificar que el valor es exactamente []y no algo falso de otro tipo, entonces seguramente if a == []:se requiere, en lugar de burlarse de isinstance.
RemcoGerlich
2
Sin ==embargo, hay algunas coacciones automáticas . Fuera de mi cabeza, no puedo identificar ninguno []. [] == ()por ejemplo regresa False. Pero por ejemplo frozenset()==set()vuelve True. Por lo tanto, al menos vale la pena pensar si algún tipo no deseado podría ser forzado [](o viceversa) al hacerlo a == [].
dubiousjim
@RemcoGerlich - isinstance () sigue siendo preferible en lugar de construir una lista vacía para comparar. Además, como otro señaló, 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 tal como la proporciona el lenguaje no debe considerarse "burlarse de , "sino más bien" buena técnica de programación ".
MrWonderful
29

De la documentación sobre la prueba del valor de verdad:

Todos los valores que no sean los que se enumeran aquí se consideran True

  • None
  • False
  • cero de cualquier tipo numérico, por ejemplo, 0, 0.0, 0j.
  • cualquier secuencia vacía, por ejemplo, '' , (), [].
  • cualquier mapeo vacío, por ejemplo {},.
  • instancias de clases definidas por el usuario, si la clase define un __bool__()o__len__() método , cuando ese método devuelve el valor entero cero o valor 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!')
Sнаđошƒаӽ
fuente
@DJ_Stuffy_K afirman qué en la prueba de unidad, ¿una lista vacía? Solo úsalo assert(not myList). Si también desea afirmar que el objeto es a list, puede usarlo assertIsInstance().
Sнаđошƒаӽ
24

Aquí hay algunas maneras en 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 (que devuelve un valor booleano ). Y un Truevalor indicaría que no está vacío.

2) Una forma muy explícita: usando el 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 anónima vacía:

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

4) Otra embargo tonta manera de hacerlo está utilizando exceptiony iter():

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

Prefiero lo siguiente:

if a == []:
   print "The list is empty."
verix
fuente
37
Esto será más lento, ya que crea una instancia de una lista vacía adicional innecesariamente.
Carl Meyer
32
esto es menos legible que if not a:y se rompe más fácilmente. Por favor no lo hagas.
devsnd
Hay un buen punto hecho anteriormente () == []también es igual a falso. Aunque me gusta cómo esta implementación lee las if not a:cubiertas en todos los casos, si definitivamente espera una lista, entonces su ejemplo debería ser suficiente.
una estrella
19

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")
Vikrant
fuente
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])

A veces es bueno probar Noney detectar el vacío 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 Noneintegridad, 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
Tagar
fuente
8

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 una lista vacía, puede hacer esto:

if isinstance(a, list) and len(a)==0:
    print("Received an empty list")
HackerBoss
fuente
Es posible que esto arroje una excepción, si ano es una lista y ano tiene un método __len__implementado. Yo recomendaría:if isinstance(obj, list): if len(obj) == 0: print '...'
Sven Krüger
44
@ SvenKrüger no. El operador andes perezoso en Python. Nada después andse ejecutará si la condición anterior andes False.
ElmoVanKielmo
7

podríamos usar un simple si más:

item_list=[]
if len(item_list) == 0:
    print("list is empty")
else:
    print("list is not empty")
l. zhang
fuente
55
-1 - Para evitar confusiones, no use palabras reservadas para nombres de variables o puede obtener un comportamiento sorprendente la próxima vez que intente llamar, por ejemplo "list ()" ... algo así como "TypeError: el objeto 'list' es no invocable "o algo así.
MrWonderful
6

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

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

Si desea verificar 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.
Rahul
fuente
1
todo (bool (x) para x en l) es verdadero para una lista vacía
gberger
5

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. - agregarand not isinstance(a,(str,unicode)) si desea excluir 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
AndreyS Scherbakov
fuente
1
Overbroad; esto solo pregunta si una lista está vacía, no si algo es un iterable vacío.
pppery
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 ser probados útilmente para el vacío.)
Davis Herring
5
print('not empty' if a else 'empty')

un poco más práctico:

a.pop() if a else None

y la versión más pura:

if a: a.pop() 
Andrey Suglobov
fuente
4

Desde python3 en adelante puedes usar

a == []

para verificar 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 directo

Tessaracter
fuente
1
¿Puede dar más explicaciones sobre cómo funciona sin escribir "if"?
ganeshdeshmukh
3
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.
MrWonderful
@MrWonderful no crea una instancia de una lista vacía cada vez. Simplemente verifica si la lista existente aestá vacía o no.
Tessaracter
@ MrWonderful No entiendo lo que lo hacepythonic
Tessaracter
@ganeshdeshmukh si lo usa a==[]se imprimirá verdadero en la terminal de python si a está vacío. De lo contrario, se imprimirá False. Puede usar esto dentro de una condición if también comoif(a==[])
Tessaracter
3

Incluso puedes intentar usar bool () como este

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

Me encanta esta forma de comprobar que la lista está vacía o no.

Muy práctico y útil.

Sunil Lulla
fuente
44
Para aquellos (como yo) que no 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.
Galen Long
Esto se puede usar en una expresión y es más conciso.
qneill
3

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 usar 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).

Vineet Jain
fuente
3
El nombre is_emptysugiere que devuelve algo. Pero si lo hiciera, ese algo sería bool(any_structure), lo que deberías usar en su lugar ( cuando necesites un bool).
Davis Herring
44
¿Por qué queremos una variación en booleso (también) imprime mensajes a la salida estándar?
Davis Herring
@DavisHerring Siempre tenemos dos opciones: primero imprimir usando la función y otra usando la boolvariable de retorno . La elección es tuya. Escribo ambos para que puedas elegir entre ellos.
Vineet Jain
3

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

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

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

MiloMinderbinder
fuente
1

Lo que me trajo aquí es un caso de uso especial: en realidad quería que una función 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 que "no está vacío" se necesita explícitamente como una función, booles la mejor opción.

Vedran Šego
fuente
1

Para verificar si una lista está vacía o no, puede usar las dos formas siguientes. Pero recuerde, debemos evitar la forma de verificar explícitamente un tipo de secuencia (es una less pythonicforma):

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 segunda forma es una more pythonic. Este método es una forma implícita de verificación y mucho más preferible que la anterior.

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.

Andy
fuente