Atualmente estou fazendo isso:
try:
something = iterator.next()
# ...
except StopIteration:
# ...
Mas gostaria de uma expressão que pudesse colocar dentro de uma if
declaração simples . Existe algo integrado que tornaria este código menos desajeitado?
any()
retorna False
se um iterável estiver vazio, mas irá potencialmente iterar sobre todos os itens se não estiver. Eu só preciso verificar o primeiro item.
Alguém pergunta o que estou tentando fazer. Escrevi uma função que executa uma consulta SQL e produz seus resultados. Às vezes, quando chamo essa função, só quero saber se a consulta retornou algo e tomar uma decisão com base nisso.
Respostas:
any
não irá além do primeiro elemento se for True. No caso de o iterador gerar algo falso, você pode escreverany(True for _ in iterator)
.fonte
any((x > 100 for x in xrange(10000000)))
e depois corraany((x > 10000000 for x in xrange(100000000)))
- o segundo deve demorar muito mais.sum(1 for _ in itertools.islice(iterator, max_len)) >= max_len
all(False for _ in iterator)
irá verificar se o iterador está vazio. (all retorna True se o iterador estiver vazio, caso contrário, ele para quando vê o primeiro elemento False)No Python 2.6+, se o nome
sentinel
estiver vinculado a um valor que o iterador não pode produzir,Se você não tem ideia do que o iterador pode produzir, faça seu próprio sentinela (por exemplo, no topo do seu módulo) com
Caso contrário, você poderia usar, na função de sentinela, qualquer valor que você "saiba" (com base nas considerações do aplicativo) que o iterador não pode produzir.
fonte
if not next(iterator, None):
era suficiente, pois eu tinha certeza de que Nenhum não faria parte dos itens. Obrigado por me apontar na direção certa!not
retornará True para qualquer objeto falso, como listas vazias, False e zero.is not None
é mais seguro e, na minha opinião, mais claro.Isso não é realmente mais limpo, mas mostra uma maneira de empacotá-lo em uma função sem perdas:
Isso não é realmente pythônico e, para casos particulares, provavelmente existem soluções melhores (mas menos gerais), como o próximo padrão.
Isso não é geral porque None pode ser um elemento válido em muitos iteráveis.
fonte
next()
.tee
itertools terão que manter todos os elementos do iterador original para o caso deany_check
precisar avançar. Isso é pior do que apenas converter o iterador original em uma lista.você pode usar:
mas é um pouco não explicativo para o leitor de código
fonte
A melhor maneira de fazer isso é com um
peekable
demore_itertools
.Apenas tome cuidado se você mantiver as referências para o iterador antigo, pois ele se tornará avançado. Você tem que usar o novo iterador peekable a partir de então. Na verdade, porém, peekable espera ser o único pedaço de código modificando aquele antigo iterador, então você não deve manter referências para o antigo iterador por aí.
fonte
A respeito:
fonte
class NotSet: pass
e verifique se háif next(i, NotSet) is NotSet: print("Iterator is empty")
__length_hint__
estima a duração delist(it)
- é um método privado, embora:fonte
Este é um invólucro de iterador exagerado que geralmente permite verificar se há um próximo item (via conversão para booleano). Claro, muito ineficiente.
Resultado:
fonte
Um pouco tarde, mas ... Você poderia transformar o iterador em uma lista e depois trabalhar com essa lista:
fonte