python - variavel - Como faço para verificar se uma lista está vazia?




verificar se lista esta vazia java (20)

Por exemplo, se passou o seguinte:

a = []

Como faço para verificar se a está vazia?

https://code.i-harness.com


Melhor maneira de verificar se uma lista está vazia

Por exemplo, se passou o seguinte:

a = []

Como faço para verificar se a está vazia?

Resposta curta:

Coloque a lista em um contexto booleano (por exemplo, com uma instrução if ou while ). Ele testará False se estiver vazio e True caso contrário. Por exemplo:

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

Apelo à Autoridade

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

Para sequências, (strings, listas, tuplas), use o fato de que seqüê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

Eu 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 ser tentados a fazer isso:

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

Eles estão corretos em seus respectivos idiomas. E isso é até mesmo semanticamente correto em Python.

Mas nós o consideramos não-Python porque o Python suporta essas semânticas diretamente na interface do objeto de lista através da coerção booleana.

A partir dos docs (e observe especificamente a inclusão da lista vazia, [] ):

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

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

E a documentação do modelo de dados:

object.__bool__(self)

Chamado para implementar testes de valor verdade e a operação bool() ; deve retornar False ou True . Quando esse método não é definido, __len__() é chamado, se estiver 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 len() . Deve retornar o comprimento do objeto, um inteiro> = 0. Além disso, um objeto que não define um __bool__() e cujo método __len__() retorna zero é considerado falso em um contexto booleano.

Então, ao invés 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')

Fazendo o que o Pythonic geralmente compensa no desempenho:

Isso vale a pena? (Note que menos tempo para realizar 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, aqui está 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 de comprimento com a função interna len comparação a 0 ou a verificação em relação a uma lista vazia é muito menos eficiente do que usar a sintaxe integrada da linguagem conforme documentada.

Por quê?

Para o len(a) == 0 verifique:

Primeiro o Python precisa verificar os globals para ver se o len está sombreado.

Em seguida, ele deve chamar a função, load 0 e 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 o [] == [] ele tem que construir uma lista desnecessária e, novamente, fazer a operação de comparação na máquina virtual do Python (em oposição a C)

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

O modo "Pythonic" é muito mais simples e rápido, já que o tamanho 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 C e documentação

PyVarObject

Esta é uma extensão do PyObject que adiciona o campo ob_size . Isso é usado apenas para objetos que possuem alguma noção de comprimento. Esse tipo não aparece com frequência na API do Python / C. Corresponde aos campos definidos pela expansão da macro PyObject_VAR_HEAD .

Da 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

Eu gostei de pesquisar isso e passo muito tempo cuidando das minhas respostas. Se você acha que estou deixando algo de fora, por favor, deixe-me saber em um comentário.


Por que verificar em tudo?

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

Eu diria que a maneira mais pythonic é não verificar, mas apenas processar a lista. Dessa forma, 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 lidar com qualquer conteúdo de um , sem exigir uma verificação específica de vazio. Se a estiver vazio, o bloco dependente não será executado e o interpretador passará para a próxima linha.

Se você realmente precisa checar se a matriz está vazia, as outras respostas são suficientes.


Alguns métodos que eu uso:

if not a:
    print "list is empty"


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

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

a = [] #the list

1) A maneira pythonic bem simples:

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

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

2) Uma maneira muito explícita: usando 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 tola de fazer é usar exception e iter() :

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

Eu escrevi:

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

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

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 do @ 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 sair sem a verificação de tipo explícito, mas somente se o contexto circundante já lhe garantir que a é um valor dos tipos que você está preparado para manipular, ou se tiver certeza de que os tipos que você não está preparado para manipular são Ir para levantar erros (por exemplo, um TypeError se você chamar len em um valor para o qual é indefinido) que você está preparado para manipular. Em geral, as convenções "pítonicas" parecem seguir este último caminho. Aperte-o como um pato e deixe-o levantar um DuckError se ele não souber como fazer um charlatão. Você ainda tem que pensar sobre quais tipos de suposições você está fazendo, e se os casos em que você não está preparado para lidar adequadamente realmente vão errar nos lugares certos. Os arrays Numpy são um bom exemplo onde depender apenas do len ou do typecast booleano pode não fazer exatamente o que você está esperando.


Eu prefiro explicitamente:

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

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


Eu vi o abaixo como preferido:

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

Maneira simples é verificar se o comprimento é igual a zero.

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

Outra maneira simples poderia ser

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

Python é muito uniforme quanto ao tratamento do vazio. Dado o seguinte:

a = []

.
.
.

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

Basta marcar a lista a com uma instrução "if" para ver se está vazia. Pelo que li e fui ensinado, esta é a maneira "Pythonic" de ver se uma lista ou tupla está vazia.


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

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

@ Daren Thomas

EDIT: Outro ponto contra o teste da lista vazia como False: E quanto ao polimorfismo? Você não deve depender de uma lista ser uma lista. Deveria apenas grasnar como um pato - como você vai pegar o seu duckCollection para grasnar '' False '' quando não tem elementos?

Seu duckCollection deve implementar __nonzero__ ou __len__ para que o if: funcione sem problemas.


Você pode até tentar usar bool () como este

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

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

Muito útil e útil.


Outras pessoas parecem estar generalizando a questão além de apenas listas, então eu pensei em adicionar uma ressalva para um tipo diferente de sequência que muitas pessoas poderiam usar, especialmente porque este é o primeiro hit do google para "array vazio de teste de python" .

Outros métodos não funcionam para matrizes numpy

Você precisa ter cuidado com matrizes numpy, porque outros métodos que funcionam bem para list s ou outros recipientes padrão falham para matrizes numpy. Eu explico porque abaixo, mas em resumo, o método preferido é usar size .

A maneira "pythonic" não funciona: Parte 1

A maneira "pythonic" falha com matrizes numpy porque numpy tenta converter a matriz para uma matriz de bool s, e if x tenta avaliar todos esses bool s de uma vez por algum tipo de valor de verdade agregado. Mas isso não faz sentido, então você recebe um 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()

A maneira "pythonic" não funciona: parte 2

Mas pelo menos o caso acima diz que falhou. Se acontecer de você ter um array numpy com exatamente um elemento, a instrução if irá "funcionar", no sentido de que você não recebe um erro. No entanto, se esse elemento for 0 (ou 0.0 , ou false , ...), a instrução if incorretamente resultará em false :

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

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

Usando len pode dar resultados inesperados

Por exemplo,

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

retorna 1, mesmo que a matriz tenha zero elementos.

O caminho numpitônico

Conforme explicado na FAQ do scipy , o método correto em todos os casos em que você sabe que tem um array 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 tiver certeza se pode ser uma list , um array numpy ou qualquer outra coisa, você pode combinar essa abordagem com a resposta @dubiousjim dá para garantir que o teste correto seja usado para cada tipo. Não muito "pythonic", mas acontece que o numpy intencionalmente quebrou a pythonicity pelo menos nesse sentido.

Se você precisa fazer mais do que apenas verificar se a entrada está vazia, e você está usando outros recursos numpy como indexação ou operações matemáticas, provavelmente é mais eficiente (e certamente mais comum) forçar a entrada a ser um array numpy. Existem algumas funções interessantes para fazer isso rapidamente - o mais importante é numpy.asarray . Isso leva sua entrada, não faz nada se já é uma matriz, ou envolve sua entrada em uma matriz se for uma lista, tupla, etc. e, opcionalmente, converte-a para o tipo dtype escolhido. Portanto, é muito rápido sempre que pode ser, e garante que você considere que a entrada é um array numpy. Geralmente, usamos apenas o mesmo nome, pois a conversão para uma matriz não retornará para fora do scope atual:

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

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


A resposta de Patrick (aceita) 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 ideia seguir o idioma - mesmo que você ache que não é explícito o suficiente ou confuso para os usuários Ruby ou o que for.

O código Python e a comunidade Python possuem idiomas muito fortes. Seguir esses idiomas torna seu código mais fácil de ler para qualquer pessoa experiente em Python. E quando você viola esses idiomas, isso é um sinal forte.

É verdade que, if not a: não distingue listas vazias de None , ou 0 numérico, ou tuplas vazias, ou tipos de coleção vazios criados pelo usuário, ou tipos não-completamente-coleção criados pelo usuário ou matriz NumPy de elemento único atuando como escalares com valores falsey, etc. E às vezes é importante ser explícito sobre isso. E nesse caso, você sabe o que você quer ser explícito, então você pode testar exatamente isso. Por exemplo, if not a and a is not None: significa "anything falsey except None", while 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ê quer testar, isso também indica ao leitor que este teste é importante.

Mas quando você não tem nada para ser explícito, qualquer coisa diferente de if not a: é if not a: enganar o leitor. Você está sinalizando algo tão importante quando não é. (Você também pode tornar o código menos flexível, ou mais lento, ou o que for, mas isso é menos importante.) E se você habitualmente enganar o leitor assim, então quando você precisar fazer uma distinção, ele passará despercebido porque você foi "lobo chorando" em todo o seu código.


De python3 em diante você pode usar

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

para verificar se a lista está vazia

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

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


Se você quiser verificar se a lista está vazia;

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

Se você quiser verificar o tempo, todos os valores da lista estarão vazios.

if empty_list(lst):
    # do your stuff.

No entanto, isso será True para a lista vazia.

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

Agora você pode usar:

a.pop() if a else None

Veja o seguinte código executado no terminal interativo do 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 >>> 

O valor de verdade de uma lista vazia é Falsepara uma lista não vazia True.


a == []

um pouco mais prático:

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

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 None e 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 a pena, nada é falso. Então, se você não quiser separar o teste para None -ness, você 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




is-empty