Como verifico se uma lista está vazia?


3234

Por exemplo, se passou o seguinte:

a = []

Como verifico se aestá vazio?

Respostas:


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

Usar a booleanidade implícita do vazio listé bastante pitônico.


1130
Brincando de advogado do diabo. Não entendo por que esse idioma é considerado pitônico. 'Explícito é melhor que implícito', correto? Essa verificação não parece muito explícita sobre o que está sendo verificado.
James McMahon

222
@ JamesMcMahon - é uma troca entre explicitação e flexibilidade de tipo. geralmente, "ser explícito" significa não fazer coisas "mágicas". por outro lado, "digitação de pato" significa trabalhar com interfaces mais gerais, em vez de verificar explicitamente os tipos. então algo como if a == []está forçando um tipo específico ( () == []é False). aqui, parece haver consenso geral de que a digitação com patos vence (na verdade, dizendo que essa __nonzero__é a interface para testar o vazio docs.python.org/reference/datamodel.html#object.__nonzero__ )
andrew cooke

38
Este método não funciona em matrizes numpy .. então acho que se len (a) == 0 é preferível tanto em termos de "digitação de pato" quanto em implicitividade.
Mr.WorshipMe

10
A maneira canônica de saber se uma matriz em C está vazia é desreferenciar o primeiro elemento e verificar se é nulo, assumindo uma matriz com terminação nula. Caso contrário, comparar seu comprimento com zero é totalmente ineficiente se a matriz tiver um tamanho significativo. Além disso, normalmente, você não alocaria memória para uma matriz vazia (o ponteiro permanece nulo); portanto, não faz sentido tentar obter seu comprimento. Não estou dizendo que len (a) == 0 não é uma boa maneira de fazê-lo, apenas não grita 'C' para mim quando o vejo.
Sleblanc #

6
@BrennenSprimont, Se não tiver terminação nula, você já saberá o comprimento, se está armazenado em uma variável separada ou se sua matriz está envolvida em algum contêiner que rastreia o comprimento. C ++, Java, C # possuem esses contêineres e implementam algum método de "comprimento" com eficiência. C não tem tal coisa , você precisa rolar sozinho. Matrizes C alocadas estaticamente são apenas ponteiros para um espaço de memória que garante espaço suficiente para armazenar a quantidade de dados solicitada. Não há nada incorporado em C que permita saber quanto você já preencheu esse espaço.
Sleblanc 14/04/19

1159

A maneira pitônica de fazer isso é no guia de estilo do PEP 8 (onde Sim significa "recomendado" e Não significa "não recomendado"):

Para seqüências (strings, listas, tuplas), use o fato de que sequências vazias são falsas.

Yes: if not seq:
     if seq:

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

49
A segunda maneira parece melhor se você deseja sinalizar que seqse espera que seja algum tipo de objeto parecido com uma lista.
BallpointBen

5
@BallpointBen que, defensores Pythonism diria, deve ser implícita na forma como a variável é chamada, tanto quanto possível
axolotl

9
@BallpointBen tente usar a dica de tipo do Python para sinalizar o que uma variável deve ser. Foi introduzido no 3.5.
Boris

8
numpy quebrou esse idioma ... seq = numpy.array ([1,2,3]) seguido por seq seq gera uma exceção "ValueError: O valor verdadeiro de uma matriz com mais de um elemento é ambíguo. Use a.any () ou a.all () "
Mr.WorshipMe 20/03/19

2
@ jeronimo: Eu acredito que é um aviso específico para o lxml.
Harley Holcombe

768

Eu prefiro explicitamente:

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

Dessa forma, é 100% claro que lié uma sequência (lista) e queremos testar seu tamanho. Meu problema if not li: ...é que ele dá a falsa impressão de que lié uma variável booleana.


91
Verificar se o comprimento de uma lista é igual a zero, em vez de apenas verificar se a lista é falsa, é feio e não-tônico. Qualquer pessoa familiarizada com o Python não vai pensar que lié um bool e não se importará. Se for importante, você deve adicionar um comentário, não mais código.
9788 Carl Smith

21
Parece um teste desnecessariamente preciso, que geralmente é mais lento e é sempre menos legível no IMHO. Em vez de verificar o tamanho de algo vazio, por que não apenas verificar se está vazio?
John B

34
De qualquer forma, a razão pela qual isso é ruim (e violar expressões idiomáticas em uma linguagem com expressões fortes como Python é ruim em geral) é que sinaliza ao leitor que você está verificando especificamente a duração por algum motivo (por exemplo, porque você deseja Noneou não 0para criar uma exceção em vez de passar). Então, quando você faz isso sem razão, que é enganosa e isso também significa que quando o código faz necessidade de fazer a distinção, a distinção é invisível porque você "lobo gritou" todo o resto da fonte.
abarnert

18
Eu acho que isso está apenas desnecessariamente aumentando o código. Caso contrário, por que não ser ainda mais "explícito" if bool(len(li) == 0) is True:?
Augurar

11
@Jabba, será O (1) em muitos casos (aqueles em que você trabalha com os tipos de dados internos), mas você simplesmente não pode confiar nisso. Você pode estar trabalhando com um tipo de dados personalizado que não possui essa propriedade. Você também pode optar por adicionar esse tipo de dados personalizado posteriormente, depois de escrever esse código.
ralokt

324

Este é o primeiro hit do Google para "array vazio de teste python" e consultas semelhantes, além de outras pessoas parecerem generalizar a questão além de apenas listas, então pensei em adicionar uma advertência para um tipo diferente de sequência que muitas pessoas pode usar.

Outros métodos não funcionam para matrizes NumPy

Você precisa ter cuidado com as matrizes NumPy, porque outros métodos que funcionam bem para lists ou outros contêineres padrão falham nas matrizes NumPy. Eu explico o porquê abaixo, mas, resumindo, o método preferido é usar size.

O caminho "pitônico" não funciona: Parte 1

A maneira "pitônica" falha com as matrizes NumPy porque o NumPy tenta converter a matriz em uma matriz de bools e if xtenta avaliar todos esses bools ao mesmo tempo para algum tipo de valor agregado de verdade. Mas isso não faz sentido, então você recebe 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()

O caminho "pitônico" não funciona: Parte 2

Mas pelo menos o caso acima diz que ele falhou. Se você tiver uma matriz NumPy com exatamente um elemento, a ifinstrução "funcionará", no sentido de que você não recebe um erro. No entanto, se esse elemento for 0(ou 0.0, ou False...), a ifinstrução resultará incorretamente em False:

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

Mas xexiste claramente e não está vazio! Este resultado não é o que você queria.

Usar lenpode gerar resultados inesperados

Por exemplo,

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

retorna 1, mesmo que a matriz tenha zero elementos.

O caminho numptônico

Conforme explicado nas Perguntas frequentes do SciPy , o método correto em todos os casos em que você sabe que possui uma matriz NumPy é 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

Se você não tem certeza se pode ser um list, um array NumPy ou qualquer outra coisa, você pode combinar essa abordagem com a resposta que @dubiousjim fornece para garantir que o teste correto seja usado para cada tipo. Não é muito "pitônico", mas acontece que o NumPy intencionalmente quebrou a pitonicidade, pelo menos nesse sentido.

Se você precisar fazer mais do que apenas verificar se a entrada está vazia e estiver usando outros recursos do NumPy, como operações de indexação ou matemática, é provavelmente mais eficiente (e certamente mais comum) forçar a entrada a ser uma matriz NumPy. Existem algumas funções interessantes para fazer isso rapidamente - o mais importante numpy.asarray. Isso pega sua entrada, não faz nada se já é uma matriz ou agrupa sua entrada em uma matriz se for uma lista, tupla etc., e, opcionalmente, a converte para a sua escolhida dtype. Portanto, é muito rápido, sempre que possível, e garante que você apenas assuma que a entrada é uma matriz NumPy. Normalmente, usamos apenas o mesmo nome, pois a conversão em uma matriz não retorna ao escopo atual :

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

Isso fará com que a x.sizeverificação funcione em todos os casos que vejo nesta página.


62
Vale a pena notar que isso não é uma falha no Python, mas sim uma quebra intencional do contrato numpy- numpyé uma biblioteca com um caso de uso muito específico e possui uma definição "natural" diferente do que a veracidade em uma matriz é para o Padrão Python para contêineres. Faz sentido otimizar para esse caso, da maneira que pathlibcostuma /concatenar caminhos em vez de +- não é padrão, mas faz sentido no contexto.
precisa

9
Acordado. O que quero dizer é que é importante lembrar que o numpy optou por interromper a digitação de patos tanto para os idiomas mais comuns if xquanto para os len(x)idiomas - e às vezes essa quebra pode ser muito difícil de detectar e depurar.
1655 Mike

22
Não sei, para mim, se um método chamado len (x) não retorna o comprimento da matriz por suposições, seu nome é mal projetado.
Dalton

11
Esta questão não tem nada a ver com matrizes numpy
pppery

19
@ppperry Sim, a pergunta original não era sobre matrizes Numpy, mas ao trabalhar com esses argumentos e, possivelmente, com tipos de pato, essa pergunta se torna muito relevante.
Peterhil #

223

Melhor maneira de verificar se uma lista está vazia

Por exemplo, se passou o seguinte:

a = []

Como verifico se um está vazio?

Resposta curta:

Coloque a lista em um contexto booleano (por exemplo, com uma instrução ifou while). Ele testará Falsese está vazio ou Truenão. Por exemplo:

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

PEP 8

O PEP 8 , o guia de estilo oficial do Python para código Python na biblioteca padrão do Python, afirma:

Para seqüências (strings, listas, tuplas), use o fato de que sequências vazias são falsas.

Yes: if not seq:
     if seq:

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

Devemos esperar que o código da biblioteca padrão seja o mais eficiente e correto possível. Mas por que esse é o caso e por que precisamos dessa orientação?

Explicação

Frequentemente vejo código como este de programadores experientes novos no Python:

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

E os usuários de idiomas preguiçosos podem ficar tentados a fazer isso:

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

Eles estão corretos nos respectivos idiomas. E isso é semanticamente correto no Python.

Mas consideramos isso não-pitonico porque o Python suporta essas semânticas diretamente na interface do objeto de lista por meio de coerção booleana.

Nos documentos (e observe especificamente a inclusão da lista vazia []):

Por padrão, um objeto é considerado verdadeiro, a menos que sua classe defina um __bool__()método que retorne Falseou um __len__()método que retorne zero, quando chamado com o objeto. Aqui estão a maioria dos objetos internos considerados falsos:

  • constantes definidas como falsas: Nonee False.
  • zero, de qualquer tipo numérico: 0, 0.0, 0j, Decimal(0),Fraction(0, 1)
  • sequências de vazios e colecções: '', (), [], {}, set(),range(0)

E a documentação do modelo de dados:

object.__bool__(self)

Chamado para implementar testes de valor de verdade e a operação interna bool(); deve retornar Falseou True. Quando esse método não é definido, __len__()é chamado, se definido, e o objeto é considerado verdadeiro se o resultado for diferente de zero. Se uma classe não define nem __len__() nem __bool__(), todas as suas instâncias são consideradas verdadeiras.

e

object.__len__(self)

Chamado para implementar a função interna len(). Deve retornar o comprimento do objeto, um número inteiro> = 0. Além disso, um objeto que não define um __bool__()método e cujo __len__()método retorna zero é considerado falso em um contexto booleano.

Então, em vez disso:

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

ou isto:

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

Faça isso:

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

Fazer o que é Pythonic geralmente compensa no desempenho:

Vale a pena? (Observe que menos tempo para executar uma operação equivalente é melhor :)

>>> 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 escala, eis o custo de chamar a função e construir e retornar uma lista vazia, que você pode subtrair dos custos das verificações de vazio usadas acima:

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

Vemos que a verificação do comprimento com a função interna lencomparada 0 ou a verificação de uma lista vazia tem muito menos desempenho do que o uso da sintaxe interna do idioma, conforme documentado.

Por quê?

Para a len(a) == 0verificação:

Primeiro, o Python precisa verificar as globais para ver se lenestá sombreado.

Em seguida, ele deve chamar a função, carregar 0e fazer a comparação de igualdade no Python (em vez de com 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

E para [] == []isso ele precisa criar uma lista desnecessária e, novamente, fazer a operação de comparação na máquina virtual do Python (ao contrário de C)

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

A maneira "Pythonic" é uma verificação muito mais simples e rápida, pois o comprimento da lista é armazenado em cache no cabeçalho da instância do objeto:

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

Evidência da fonte e documentação C

PyVarObject

Esta é uma extensão PyObjectque adiciona o ob_sizecampo. Isso é usado apenas para objetos que tenham alguma noção de comprimento. Esse tipo geralmente não aparece na API Python / C. Corresponde aos campos definidos pela expansão da PyObject_VAR_HEADmacro.

Na fonte c em 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

Resposta aos comentários:

Gostaria de salientar que isso também é verdade para o caso não vazio embora o seu muito feio como com l=[]em seguida, %timeit len(l) != 090,6 ns ± 8,3 ns, %timeit l != []55,6 ns ± 3,09, %timeit not not l38,5 ns ± 0,372. Mas não há como alguém gostar, not not lapesar do triplo da velocidade. Parece ridículo. Mas a velocidade vence,
suponho que o problema esteja sendo testado com o tempo, uma vez que apenas if l:é suficiente, mas surpreendentemente %timeit bool(l)gera 101 ns ± 2,64 ns. Interessante não há como coagir a bool sem essa penalidade. %timeit lé inútil, pois nenhuma conversão ocorreria.

A magia do IPython,, %timeitnão é totalmente inútil aqui:

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 há um pouco de custo linear para cada adicional notaqui. Queremos ver os custos, ceteris paribus , ou seja, tudo o mais igual - onde tudo o mais é minimizado na medida do possível:

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)

Agora vamos ver o caso de uma lista de desempregados:

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)

O que podemos ver aqui é que faz pouca diferença se você passa em um bool para a condição ou a própria lista e, se houver, fornecer a lista, como é, é mais rápido.

Python é escrito em C; ele usa sua lógica no nível C. Tudo o que você escreve em Python será mais lento. E provavelmente haverá ordens de magnitude mais lentas, a menos que você esteja usando os mecanismos embutidos no Python diretamente.


Gostaria de salientar que isso também é verdade para o caso não vazio embora o seu muito feio como com l=[]em seguida, %timeit len(l) != 090,6 ns ± 8,3 ns, %timeit l != []55,6 ns ± 3,09, %timeit not not l38,5 ns ± 0,372. Mas não há como alguém gostar, not not lapesar do triplo da velocidade. Parece ridículo. Mas a velocidade vence
Gregory Morse

Suponho que o problema esteja sendo testado com o tempo, uma vez que apenas if l:é suficiente, mas surpreendentemente %timeit bool(l)gera 101 ns ± 2,64 ns. Interessante não há como coagir a bool sem essa penalidade. %timeit lé inútil, pois nenhuma conversão ocorreria.
Gregory Morse

139

Uma lista vazia é considerada falsa no teste de valor verdadeiro (consulte a documentação do python ):

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

@Daren Thomas

EDIT: Outro ponto contra testar a lista vazia como False: E o polimorfismo? Você não deve depender de uma lista ser uma lista. Ele deveria grasnar como um pato - como você fará sua coleção de pato gritar '' False '' quando não possui elementos?

Sua duckCollection deve implementar __nonzero__ou __len__então o if a: funcionará sem problemas.


Estranho como [] == Falseirá avaliar a embora Falso
information_interchange

@information_interchange Se você deseja verificar explicitamente a veracidade de um valor, use bool(). bool([]) == Falseserá avaliado Trueconforme o esperado.
Augurar

103

A resposta (aceita) de Patrick está certa: if not a:é o caminho certo para fazê-lo. A resposta de Harley Holcombe está certa de que isso está no guia de estilo do PEP 8. Mas o que nenhuma das respostas explica é por que é uma boa idéia seguir o idioma - mesmo se você achar pessoalmente que não é explícito o suficiente ou confuso para os usuários do Ruby ou o que seja.

O código Python e a comunidade Python têm expressões muito fortes. Seguir essas expressões facilita a leitura do código para qualquer pessoa com experiência em Python. E quando você viola esses idiomas, esse é um sinal forte.

É verdade que if not a:não distingue listas vazias de None, ou 0 numéricas, tuplas vazias, tipos de coleções criadas pelo usuário ou tipos de coleções que não são completamente vazias criadas pelo usuário ou matriz NumPy de elemento único que atua como escalares com falsey valores, etc. E, às vezes, é importante ser explícito sobre isso. E, nesse caso, você sabe sobre o que deseja ser explícito, para poder testar exatamente isso. Por exemplo, if not a and a is not None:significa "qualquer coisa falsa, exceto Nenhuma", enquanto if len(a) != 0:significa "apenas sequências vazias - e qualquer coisa além de uma sequência é um erro aqui" e assim por diante. Além de testar exatamente o que você deseja testar, isso também sinaliza ao leitor que esse teste é importante.

Mas quando você não tem nada a ser explícito, algo além de if not a:engana o leitor. Você está sinalizando algo tão importante quando não é. (Você também pode ser tornar o código menos flexível, ou mais lento, ou o que quer, mas isso é tudo menos importante.) E se você habitualmente enganar o leitor como este, então, quando você fazer necessidade de fazer uma distinção, que vai passar porque despercebida você esteve "chorando lobo" em todo o seu código.


78

Por que verificar?

Parece que ninguém resolveu questionar sua necessidade de testar a lista em primeiro lugar. Como você não forneceu nenhum contexto adicional, posso imaginar que você talvez não precise fazer essa verificação em primeiro lugar, mas não está familiarizado com o processamento de lista no Python.

Eu diria que a maneira mais pitônica é não checar, mas apenas processar a lista. Dessa forma, ele fará a coisa certa, vazia ou cheia.

a = []

for item in a:
    <do something with item>

<rest of code>

Isso tem o benefício de manipular qualquer conteúdo de a , embora não exija uma verificação específica quanto ao vazio. Se a estiver vazio, o bloco dependente não será executado e o intérprete passará para a próxima linha.

Se você realmente precisa verificar o vazio da matriz, as outras respostas são suficientes.


3
A questão é, verificar se a lista está vazia é muito importante, pelo menos para mim. Você já pensou se existe algum script dentro <rest of code>que possa usar o resultado do forloop? Ou use diretamente alguns valores em a? De fato, se o script for projetado para executar com entrada estritamente controlada, a verificação poderá ser um pouco desnecessária. Mas, na maioria dos casos, a entrada varia e a verificação geralmente é melhor.
Amarth Gul

Respeitosamente, não. O que eu considerei foi alguém que não sabia o suficiente sobre Python para saber que “se <list>:” era a resposta correta, perguntou como procurar uma lista vazia. Então, noto MUITAS respostas que ofereceram opiniões diferentes, mas nenhuma parecia atender à necessidade original. Foi isso que tentei fazer com a minha resposta - peça que examinem a necessidade antes de continuar. Acredito que sugeri isso na minha resposta, explicitamente.
21718 MrWonderful

@ AmarthGûl - Como é possível obter os resultados do loop for para o script dentro do <resto do código> a ser processado? Em uma lista, talvez? Ou talvez um ditado? Nesse caso, a mesma lógica se aplica. Não estou entendendo como a entrada variável pode ter algum efeito em qualquer tipo de código razoavelmente projetado, onde o processamento de uma lista vazia seria uma má idéia.
21418 MrWonderful

Um pouco antigo, mas se você estava apenas verificando se a lista estava vazia, para uma lista não vazia, seu código repete o processo repetidamente quando o OP está simplesmente procurando uma operação de verificação. Basta imaginar um cenário de pior caso para esse código como n se aproxima do infinito ....
DJK

7
@ DJJ - Não, acho que você ainda está perdendo. Presumivelmente, você deseja fazer algo com uma lista, se tiver uma. O que você faria de diferente se estivesse vazio? Voltar cedo? E se não estiver vazio? processe? O ponto é, ainda assim, que você provavelmente não precisa procurar uma lista vazia, apenas itere-a e faça o que quiser com os elementos. Se não houver elementos, você cai. Se houver elementos, você os processa conforme necessário. A questão é NÃO usar o exemplo FOR de uma verificação vazia, mas, em vez disso, NÃO verificar, basta processar a lista.
MrWonderful


40

Eu tinha escrito:

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

que foi votado com -1. Não tenho certeza se isso ocorre porque os leitores se opuseram à estratégia ou pensaram que a resposta não foi útil como apresentada. Vou fingir que foi o último, já que - o que quer que seja considerado "pitônico" - esta é a estratégia correta. A menos que você já tenha descartado ou esteja preparado para lidar com casos em que a, por exemplo False, você precisa de um teste mais restritivo do que apenas if not a:. Você pode usar algo como isto:

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

o primeiro teste é em resposta à resposta de @ Mike, acima. A terceira linha também pode ser substituída por:

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

se você deseja aceitar apenas instâncias de tipos específicos (e seus subtipos) ou com:

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

Você pode fugir sem a verificação explícita de tipo, mas apenas se o contexto circundante já garantir que você aé um valor dos tipos que você está preparado para lidar ou se tiver certeza de que os tipos que você não está preparado para lidar estão indo para gerar erros (por exemplo, a TypeErrorse você chamar lenum valor cujo valor não está definido) com o qual está preparado para lidar. Em geral, as convenções "pitônicas" parecem seguir este último caminho. Aperte-o como um pato e deixe-o criar um DuckError se não souber grasnar. No entanto, você ainda precisa pensar em quais suposições de tipo está fazendo e se os casos que você não está preparado para lidar adequadamente realmente vão errar nos lugares certos. As matrizes Numpy são um bom exemplo em que apenas confiar cegamente emlen ou o tipo de letra booleano pode não fazer exatamente o que você espera.


3
É muito raro você ter uma lista exaustiva de 6 tipos que deseja aceitar e não ser flexível para outros tipos. Quando você precisa desse tipo de coisa, provavelmente quer um ABC. Nesse caso, provavelmente seria um dos ABCs stdlib, como collections.abc.Sizedor collections.abc.Sequence, mas pode ser aquele em que você escreve a si mesmo register(list). Se você realmente possui um código em que é importante distinguir vazio de outro falsey e também para distinguir listas e tuplas de qualquer outra sequência, isso está correto - mas não acredito que você tenha esse código.
precisa saber é o seguinte

13
A razão pela qual as pessoas não gostam disso é porque na maioria dos casos é totalmente antipático. Python é uma linguagem do tipo pato, e esse nível de codificação defensiva dificulta ativamente isso. A idéia por trás do sistema de tipos do Python é que as coisas devem funcionar desde que o objeto passe em funções da maneira que precisa. Ao fazer verificações de tipo explícitas, você está forçando o chamador a usar tipos específicos, indo contra o próprio grão do idioma. Embora ocasionalmente essas coisas sejam necessárias (excluindo seqüências de caracteres de serem tratadas como sequências), esses casos são raros e quase sempre são melhores como listas negras.
precisa

1
Se você realmente deseja verificar se o valor é exatamente []e não algo falso de outro tipo, certamente if a == []:é necessário, em vez de mexer com a instância.
RemcoGerlich

2
No ==entanto, existem algumas coerções automáticas . Do alto da minha cabeça, não consigo identificar []. [] == ()por exemplo, retorna False. Mas, por exemplo, frozenset()==set()retorna True. Portanto, vale pelo menos pensar um pouco sobre se algum tipo indesejado pode ser coagido [](ou vice-versa) ao fazê-lo a == [].
dubiousjim

@RemcoGerlich - isinstance () ainda é preferível em vez de construir uma lista vazia para comparar. Além disso, como outro apontou, o operador de igualdade pode invocar a conversão implícita de alguns tipos, o que pode ser indesejável. Não há motivo para codificar "a == []" e esse código seria definitivamente marcado como um defeito em qualquer revisão de código em que participei. Não se deve considerar o uso da ferramenta apropriada fornecida pelo idioma " , "mas" boa técnica de programação ".
MrWonderful

29

Da documentação sobre teste de valor de verdade:

Todos os valores diferentes dos listados aqui são considerados True

  • None
  • False
  • de zero de qualquer tipo numérico, por exemplo, 0, 0.0, 0j.
  • qualquer sequência de vazio, por exemplo, '', (), [].
  • qualquer mapeamento vazio, por exemplo {}.
  • exemplos de classes definidas pelo utilizador, se a classe define um __bool__()ou __len__()método, quando este método retorna o valor inteiro zero ou booleano False.

Como pode ser visto, a lista vazia []é falsa ; portanto, fazer o que seria feito com um valor booleano parece mais eficiente:

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

@DJ_Stuffy_K afirma o que em testes de unidade, uma lista vazia? Basta usar assert(not myList). Se você também deseja afirmar que o objeto é a list, pode usar assertIsInstance().
Sнаđошƒаӽ

24

Aqui estão algumas maneiras de verificar se uma lista está vazia:

a = [] #the list

1) A maneira pitônica bastante simples:

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

No Python, contêineres vazios , como listas, tuplas, conjuntos, dictos, variáveis ​​etc. são vistos como False. Pode-se simplesmente tratar a lista como um predicado ( retornando um valor booleano ). E um Truevalor indicaria que não está vazio.

2) Uma maneira muito explícita: usar o len()para encontrar o comprimento e verificar se é igual a 0:

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

3) Ou comparando-o a uma lista vazia anônima:

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

4) Outra maneira ainda boba de fazer é usar exceptione iter():

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

20

Eu prefiro o seguinte:

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

37
Isso será mais lento, pois você instancia uma lista vazia extra desnecessariamente.
22630 Carl Meyer

32
isso é menos legível if not a:e quebra mais facilmente. Por favor, não faça isso.
devsnd

Há uma boa observação feita anteriormente () == []também é igual a false. Embora eu goste de como essa implementação lê if not a:todos os casos, se você definitivamente espera uma lista, seu exemplo deve ser suficiente.
A Star

19

Método 1 (preferencial):

if not a : 
   print ("Empty") 

Método 2:

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

Método 3:

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

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

Às vezes, é bom testar Nonee verificar o vazio separadamente, pois esses são dois estados diferentes. O código acima produz a seguinte saída:

list is None 
list is empty 
list has 3 elements

Embora não valha nada que Noneseja falso. Portanto, se você não deseja separar o teste para None-ness, não precisa fazer isso.

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

produz esperado

list is empty
list is empty
list has 3 elements

8

Muitas respostas foram dadas e muitas são muito boas. Eu só queria acrescentar que o cheque

not a

também passará por Nonee outros tipos de estruturas vazias. Se você realmente deseja verificar uma lista vazia, pode fazer o seguinte:

if isinstance(a, list) and len(a)==0:
    print("Received an empty list")

É possível que isso gere uma exceção, se anão for uma lista e anão tiver um método __len__implementado. Eu recomendaria:if isinstance(obj, list): if len(obj) == 0: print '...'
Sven Krüger

4
@ SvenKrüger não. O operador andé preguiçoso no Python. Nada depois andserá executado se a condição anterior andfor False.
ElmoVanKielmo

7

nós poderíamos usar um simples se mais:

item_list=[]
if len(item_list) == 0:
    print("list is empty")
else:
    print("list is not empty")

5
-1 - Para evitar confusão, não use palavras reservadas para nomes de variáveis ​​ou você poderá obter um comportamento surpreendente na próxima vez que tentar chamar, por exemplo "list ()" ... algo como "TypeError: 'list' object is não é exigível "ou algo assim.
precisa saber é o seguinte

6

Se você deseja verificar se uma lista está vazia:

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

Se você deseja verificar se todos os valores na lista estão vazios. No entanto, será Truepara uma lista vazia:

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

Se você deseja usar os dois casos juntos:

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

Agora você pode usar:

if empty_list(lst):
    # do your stuff.

1
tudo (bool (x) para x em l) é verdadeiro para uma lista vazia
gberger

5

Sendo inspirado pela solução do @ dubiousjim, proponho usar uma verificação geral adicional para saber se é algo iterável.

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

Nota: uma sequência é considerada iterável. - adicione and not isinstance(a,(str,unicode))se você deseja que a string vazia seja excluída

Teste:

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

1
Overbroad; isso é apenas perguntar se uma lista está vazia, não se algo é iterável vazio.
pppery

1
Se eu não estava feliz if a:, seria porque eu queria uma exceção se anão fosse algum tipo de contêiner. (Sendo um iteráveis também permite iterators, que não pode ser utilmente testados para vazio.)
Davis Herring

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

um pouco mais prático:

a.pop() if a else None

e versão shertest:

if a: a.pop() 

4

A partir do python3, você pode usar

a == []

para verificar se a lista está vazia

EDIT: Isso funciona com python2.7 também ..

Não sei por que existem tantas respostas complicadas. É bem claro e direto


1
por favor, dê mais explicações sobre como está funcionando sem escrever "se"?
ganeshdeshmukh

3
Isso não é pitônico nem um exemplo completo. Além disso, ele instancia uma lista vazia toda vez que é encontrada. Não faça isso.
precisa saber é o seguinte

@MrWonderful não instancia uma lista vazia todas as vezes. Apenas verifica se a lista existente aestá vazia ou não.
Tessaracter 6/04

@MrWonderful Eu não entendo o que o fazpythonic
Tessaracter 6/04

@ganeshdeshmukh, se você o usar a==[], imprimirá true no terminal python se a estiver vazio. Caso contrário, ele imprimirá Falso. Você pode usar isso dentro de uma condição if também comoif(a==[])
Tessaracter

3

Você pode até tentar usar bool () assim

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

Eu amo esse caminho para a lista de verificação está vazia ou não.

Muito útil e útil.


4
Para aqueles (como eu) que não sabiam, bool()converte uma variável Python em um booleano para que você possa armazenar a veracidade ou falsidade de um valor sem precisar usar uma declaração if. Eu acho que é menos legível do que simplesmente usar uma condicional como a resposta aceita, mas tenho certeza que existem outros bons casos de uso para ela.
Galen Long

Isso é utilizável em uma expressão e é mais conciso.
qneill

3

Simplesmente use is_empty () ou faça a função como: -

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

Pode ser usado para qualquer estrutura de dados como uma lista, tuplas, dicionário e muito mais. Por estes, você pode chamá-lo muitas vezes usando apenas is_empty(any_structure).


3
O nome is_emptysugere que ele retorne algo. Mas, se o fizesse, isso seria algo bool(any_structure)que você deveria usar ( quando precisar de um bool).
Davis Herring

4
Por que queremos uma variação booldisso (também) imprime mensagens na saída padrão?
precisa saber é o seguinte

@DavisHerring Sempre temos duas opções: imprimir usando a função other, usando a boolvariável de retorno . A escolha é sua. Eu escrevo os dois para que você possa escolher entre eles.
Vineet Jain

3

Maneira simples é verificar o comprimento é igual a zero.

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


1

O que me trouxe aqui é um caso de uso especial: eu realmente queria que uma função me dissesse se uma lista está vazia ou não. Eu queria evitar escrever minha própria função ou usar uma expressão lambda aqui (porque parecia que deveria ser bastante simples):

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

E, é claro, existe uma maneira muito natural de fazer isso:

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

Obviamente, não use boolem if(ou seja, if bool(L):) porque está implícito. Mas, para os casos em que "não está vazio" é explicitamente necessário como uma função, boolé a melhor opção.


1

Para verificar se uma lista está vazia ou não, você pode usar as duas maneiras a seguir. Mas lembre-se, devemos evitar a maneira de verificar explicitamente um tipo de sequência (é uma less pythonicmaneira):

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

O segundo caminho é more pythonicesse. Este método é uma maneira implícita de verificação e muito mais preferível que a 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 isto ajude.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.