python - vacio - ¿Cómo verifico si una lista está vacía?
saber si un array esta vacio python (30)
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 devuelvaFalse
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
yFalse
.- 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:
Llamado para implementar pruebas de valor real y la operación integrada
bool()
; Debe devolverFalse
oTrue
. 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
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.
Esta es una extensión de
PyObject
que agrega el campoob_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 macroPyObject_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.
Algunos métodos que utilizo:
if not a:
print "list is empty"
if len(a) == 0:
print "list is empty"
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 boolFalse
.
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!'')
Desde python3 en adelante puedes usar
a == []
para comprobar si la lista está vacía
EDITAR: Esto funciona con python2.7 también ..
No estoy seguro de por qué hay tantas respuestas complicadas. Es bastante claro y directo
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")
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 para comprobar la lista está vacía o no.
Muy práctico y útil.
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 Sí 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):
La forma simple es comprobar que la longitud es igual a cero.
if len(a) == 0:
print("a is empty")
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")
Prefiero lo siguiente:
if a == []:
print "The list is empty."
Legible y no tiene que preocuparse por llamar a una función como len()
para iterar a través de la variable. Aunque no estoy del todo seguro de cuál es la notación de BigO de algo como esto ... pero Python es tan increíblemente rápido que dudo que importe a menos que sea gigantesco.
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")
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, puedes llamarlo muchas veces usando solo is_empty(any_structure)
.
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.
len()
es una operación O (1) para listas, cadenas, dicts y conjuntos de Python. Python realiza un seguimiento interno de la cantidad de elementos en estos contenedores.
JavaScript tiene una noción similar de truthy / falsy .
Otras personas parecen estar generalizando la pregunta más allá de las listas, así que pensé que agregaría una advertencia para un tipo diferente de secuencia que mucha gente podría usar, especialmente porque este es el primer hit de Google para "python empty empty array" .
Otros métodos no funcionan para matrices numpy
Debe tener cuidado con las matrices numpy, ya que otros métodos que funcionan bien para la list
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 "pythonic" falla con las matrices numpy porque numpy intenta convertir la matriz en una matriz de bool
s, y if x
intenta evaluar todas esas bool
a la vez por algún tipo de valor de verdad agregado. Pero esto no tiene ningún sentido, así 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 "pythonic" no funciona: Parte 2
Pero al menos el caso anterior te dice que falló. Si resulta que tiene una matriz numpy con exactamente un elemento, la instrucción if
"funcionará", en el sentido de que no recibe un error. Sin embargo, si ese elemento es 0
(o 0.0
, o false
, ...), la instrucción if
resultará incorrectamente en false
:
>>> x = numpy.array([0,])
>>> if x: print("x")
... else: print("No x")
No x
Pero claramente x
existe y no está vacío! Este resultado no es lo que querías.
Usar len
puede 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 sobre scipy , el método correcto en todos los casos en que sepa 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 puede tratarse de una list
, una matriz numpy u otra cosa, puede combinar este enfoque con la respuesta que da @dubiousjim para asegurarse de que se usa la prueba correcta para cada tipo. No es muy "pitón", pero resulta que el entrometido rompió la pitonicidad al menos en este sentido.
Si necesita hacer algo más que comprobar si la entrada está vacía, y está usando otras funciones numéricas como la indexación o las operaciones matemáticas, probablemente sea más eficiente (y ciertamente más común) forzar la entrada para que sea una matriz numérica. Hay algunas funciones agradables para hacer esto rápidamente - lo más importante es numpy.asarray
. Esto toma su entrada, no hace nada si ya es una matriz, o envuelve su entrada en una matriz si se trata de una lista, tupla, etc. y, opcionalmente, la convierte al tipo de dtype
elegido. Así que es muy rápido siempre que puede ser, y garantiza que solo asumas que la entrada es una matriz numpy. Por lo general, incluso usamos el mismo nombre, ya que la conversión a una matriz no se realizará fuera del scope actual:
x = numpy.asarray(x, dtype=numpy.double)
Esto hará que la verificación x.size
funcione en todos los casos que veo en esta página.
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.
Mira el siguiente código ejecutado en el terminal interactivo de Python.
>>> a = []
>>> if a:
... print "List is not empty";
... else:
... print "List is empty"
...
List is empty
>>>
>>> a = [1, 4, 9]
>>> if a:
... print "List is not empty";
... else:
... print "List is empty"
...
List is not empty
>>>
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")
El valor de verdad de una lista vacía es False
mientras que para una lista no vacía es True
.
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.
print(''not empty'' if a else ''empty'')
Un poco más práctico:
a.pop() if a else None