vacio - variable vacia python




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

Por ejemplo, si pasa lo siguiente:

a = []

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


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

Por ejemplo, si 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 instrucción if o while ). Probará False si está vacío, y True contrario. Por ejemplo:

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

Apelar a la autoridad

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

Para las 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):

Debemos esperar que el código de la biblioteca estándar sea lo más eficaz y correcto posible. Pero, ¿por qué es ese el caso 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 sentirse 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 correcto semánticamente en Python.

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

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

De forma predeterminada, un objeto se considera verdadero a menos que su clase defina un __bool__() que devuelva False o un __len__() que devuelva cero, cuando se llame con el objeto. Aquí están la mayoría de los objetos incorporados considerados falsos:

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

Y la documentación del modelo de datos:

object.__bool__(self)

Llamado para implementar pruebas de valor real y la operación integrada bool() ; Debe devolver False o True . Cuando este método no está definido, se __len__() , si está definido, y el objeto se considera verdadero si su resultado es distinto de cero. Si una clase no define __len__() ni __bool__() , todas sus instancias se consideran verdaderas.

y

object.__len__(self)

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

Así que 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 por lo general vale la pena en el 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 verificaciones de vacío utilizadas anteriormente:

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

Vemos que la verificación de longitud con la función incorporada len comparación con 0 o la comparación con una lista vacía tiene mucho menos rendimiento que el uso de la sintaxis incorporada del lenguaje como se documenta.

¿Por qué?

Para el control de len(a) == 0 :

First Python tiene que comprobar los globales para ver si len está sombreado.

Luego debe llamar a la función, cargar 0 y 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 el [] == [] 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 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 PyObject que agrega el campo ob_size . Esto solo se usa para objetos que tienen cierta noción de longitud. Este tipo no aparece a menudo en la API de Python / C. Corresponde a los campos definidos por la expansión de la macro PyObject_VAR_HEAD .

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

He disfrutado investigando esto y paso mucho tiempo curando mis respuestas. Si crees que estoy dejando algo fuera, por favor házmelo saber en un comentario.


¿Por qué comprobar en absoluto?

Nadie parece haber abordado cuestionando su necesidad de probar la lista en primer lugar. Debido a que no proporcionó ningún contexto adicional, puedo imaginar que quizás no necesite realizar esta comprobació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 a , mientras que no requiere 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.


Aquí hay algunas formas 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, dados, variables, etc. se ven como False . Uno podría simplemente tratar la lista como un predicado ( devolviendo un valor booleano ). Y un valor True indicaría que no está vacío.

2) Una forma muy 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 exception e iter() :

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

De la documentation 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 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__() , cuando ese método devuelve el valor entero cero o el 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 parece más eficiente:

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

He escrito:

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

que fue votado -1. No estoy seguro de que sea porque los lectores se opusieron a la estrategia o pensaron que la respuesta no fue útil tal como se presentó. Fingiré que fue lo último, ya que --- lo que cuenta como "pythonic" --- esta es la estrategia correcta. A menos que ya haya descartado, o esté preparado para manejar casos donde a sea, por ejemplo, False , necesita una prueba más restrictiva que 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 ser reemplazada por:

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 a es un valor de los tipos que está preparado para manejar, o si está seguro de que los tipos que no está preparado para manejar son va a generar errores (por ejemplo, un TypeError si llama a len en un valor para el que no está definido) que está preparado para manejar. En general, las convenciones "pythonic" parecen ir por este último camino. Exprímelo como un pato y deja que levante un DuckError si no sabe cómo curandear. Sin embargo, aún tiene que pensar qué tipo de suposiciones está haciendo, y si los casos que no está preparado para manejar adecuadamente realmente van a cometer errores en los lugares correctos. Los arrays de Numpy son un buen ejemplo en el que basarse ciegamente en len o en el encasillado booleano puede que no haga exactamente lo que está esperando.


He visto lo siguiente como preferido:

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

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. - agrega and not isinstance(a,(str,unicode)) si quieres 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

La forma en que Pythonic lo hace es a partir de la guía de estilo PEP 8 (donde significa "recomendado" y No significa "no recomendado"):

Para las 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):

Lo prefiero explícitamente:

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

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


Otra forma sencilla podría ser

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

Python es muy uniforme en el tratamiento del vacío. Dado lo siguiente:

a = []

.
.
.

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

Simplemente verifique la lista con una declaración "if" para ver si está vacía. Por lo que he leído y enseñado, esta es la forma "Pythonic" de ver si una lista o tupla está vacía.


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

not a

También pasará por None y 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")

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

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

@Daren Thomas

EDIT: Otro punto en contra de probar la lista vacía como Falso: ¿Qué pasa con el polimorfismo? No debes depender de que una lista sea una lista. Debería simplemente curiosear como un pato: ¿cómo va a hacer que su colección de pato sea "falsa" cuando no tiene elementos?

Su duckCollection debe implementar __nonzero__ o __len__ para que el if a: funcione sin problemas.



Collection.Any () siempre devuelve false si la lista está vacía


La respuesta de Patrick (aceptada) es correcta: if not a: es la forma correcta de hacerlo. La respuesta de Harley Holcombe es correcta 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 lenguaje, incluso si personalmente encuentras 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 expresiones 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 , ni el 0 numérico, ni las tuplas vacías, ni los tipos de colección creados por el usuario vacíos, ni los tipos de colección no del todo creados por el usuario o la matriz NumPy de un solo elemento actuar como escalares con valores falseos, 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 false excepto None", 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 tiene nada de qué ser explícito, cualquier otra cosa que if not a: sea, por ejemplo, es engañosa para el lector. Estás señalando algo tan importante cuando no lo es. (También puede hacer que el código sea menos flexible, o más lento, o lo que sea, pero eso es todo menos importante). Y si habitualmente engaña al lector de esta manera, entonces cuando necesite hacer una distinción, pasará desapercibido porque Has estado "llorando lobo" por todo tu código.


Si desea comprobar si la lista está vacía;

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

Si desea verificar el clima todos los valores en la lista están vacíos.

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

Sin embargo, esto será cierto para la lista vacía.

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.

Un enfoque no oficial:

 a = []
 try:
  print(a[-1])
 except IndexError:
  print("List is empty")

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 hacer una prueba de None y de 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 None sea ​​falso. Entonces, si no quiere separar la prueba de la ausencia de None , 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

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

El uso del valor lógico implícito de la lista vacía es bastante pitónico.







is-empty