Corrija-me se eu estiver errado, mas se você pudesse criar uma solução verdadeiramente genérica para qualquer gerador, seria o equivalente a definir pontos de interrupção nas declarações de rendimento e ter a capacidade de "retroceder". Isso significaria clonar o quadro da pilha sobre rendimentos e restaurá-los no StopIteration?
Bem, acho que restaure-os StopIteration ou não, mas pelo menos o StopIteration diria que estava vazio. Sim, eu preciso dormir ... #
4
Eu acho que sei por que ele quer isso. Se você está desenvolvendo web com modelos e passando o valor de retorno para um modelo como Cheetah ou algo assim, a lista vazia []é convenientemente Falsey, então você pode fazer uma verificação se e fazer um comportamento especial para algo ou nada. Os geradores são verdadeiros mesmo que não produzam elementos.
jpsimons
Aqui está o meu caso de uso ... Estou usando glob.iglob("filepattern")um padrão curinga fornecido pelo usuário e quero avisar o usuário se o padrão não corresponder a nenhum arquivo. Claro que posso solucionar isso de várias maneiras, mas é útil poder testar com clareza se o iterador ficou vazio ou não.
A resposta simples para sua pergunta: não, não há uma maneira simples. Existem muitas soluções alternativas.
Realmente não deveria haver uma maneira simples, por causa do que são os geradores: uma maneira de gerar uma sequência de valores sem manter a sequência na memória . Portanto, não há travessia para trás.
Você pode escrever uma função has_next ou talvez até colocá-la em um gerador como um método com um decorador sofisticado, se você quiser.
justo o suficiente, isso faz sentido. eu sabia que não havia como encontrar o comprimento de um gerador, mas pensei que poderia ter perdido uma maneira de descobrir se ele inicialmente geraria alguma coisa.
Dan
1
Ah, e para referência, tentei implementar minha própria sugestão de "decorador chique". DIFÍCIL. Aparentemente, copy.deepcopy não funciona em geradores.
David Berger
47
Não sei se posso concordar com "não deve haver uma maneira simples". Existem muitas abstrações na ciência da computação projetadas para produzir uma sequência de valores sem reter a sequência na memória, mas que permitem ao programador perguntar se existe outro valor sem removê-lo da "fila", se houver. Existe uma única espiada à frente sem a necessidade de "retroceder". Isso não quer dizer que um design de iterador deve fornecer esse recurso, mas com certeza é útil. Talvez você esteja se opondo com base no fato de que o primeiro valor pode mudar após a espiada?
Larsh
9
Estou contestando o fato de que uma implementação típica nem sequer calcula um valor até que seja necessário. Pode-se forçar a interface a fazer isso, mas isso pode ser sub-ideal para implementações leves.
David Berger
6
@ S.Lott, você não precisa gerar a sequência inteira para saber se a sequência está vazia ou não. O valor de um elemento de armazenamento é suficiente - veja minha resposta.
Mark Ransom
98
Sugestão:
def peek(iterable):try:
first = next(iterable)exceptStopIteration:returnNonereturn first, itertools.chain([first], iterable)
Uso:
res = peek(mysequence)if res isNone:# sequence is empty. Do stuff.else:
first, mysequence = res
# Do something with first, maybe?# Then iterate over the sequence:for element in mysequence:# etc.
Não entendo muito bem o retorno do primeiro elemento duas vezes return first, itertools.chain([first], rest).
Njzk2
6
@ njzk2 Eu estava indo para uma operação de "espiada" (daí o nome da função). wiki "peek é uma operação que retorna o valor da parte superior da coleção sem remover o valor dos dados"
John Fouhy
Isso não funcionará se o gerador for projetado para gerar Nenhum. def gen(): for pony in range(4): yield None if pony == 2 else pony
Paul
4
@Paul Veja atentamente os valores retornados. Se o gerador estiver pronto - ou seja, não retornando None, mas aumentando StopIteration- o resultado da função é None. Caso contrário, é uma tupla, o que não é None.
Fund Monica's Lawsuit
Isso me ajudou muito no meu projeto atual. Encontrei um exemplo semelhante no código do módulo de biblioteca padrão do python 'mailbox.py'. This method is for backward compatibility only. def next(self): """Return the next message in a one-time iteration.""" if not hasattr(self, '_onetime_keys'): self._onetime_keys = self.iterkeys() while True: try: return self[next(self._onetime_keys)] except StopIteration: return None except KeyError: continue
par par
29
Uma maneira simples é usar o parâmetro opcional for next () que é usado se o gerador estiver esgotado (ou vazio). Por exemplo:
Não. Isso está incorreto para qualquer gerador em que o primeiro valor gerado seja falso.
precisa saber é o seguinte
7
Use um em object()vez de classpara torná-lo uma linha mais curta _exhausted = object():; if next(iterable, _exhausted) is _exhausted:
Messa 21/03
13
next(generator, None) is not None
Ou substitua, Nonemas o valor que você sabe que não está no seu gerador.
Edit : Sim, isso irá pular 1 item no gerador. Freqüentemente, porém, verifico se um gerador está vazio apenas para fins de validação e, na verdade, não o uso. Ou então eu faço algo como:
def foo(self):if next(self.my_generator(),None)isNone:raiseException("Not initiated")for x in self.my_generator():...
Ou seja, isso funciona se o seu gerador vier de uma função , como em generator().
Por que essa não é a melhor resposta? Caso o gerador retorne None?
Sait
8
Provavelmente porque isso força você a realmente consumir o gerador em vez de apenas testar se está vazio.
precisa saber é
3
É ruim porque no momento em que você chamar seguinte (gerador, None) você vai saltar 1 ponto, se estiver disponível
Nathan Do
Correto, você perderá o primeiro elemento do seu gen e também consumirá seu gen em vez de testar se estiver vazio.
AJ
12
A melhor abordagem, IMHO, seria evitar um teste especial. Na maioria das vezes, o uso de um gerador é o teste:
thing_generated =False# Nothing is lost here. if nothing is generated, # the for block is not executed. Often, that's the only check# you need to do. This can be done in the course of doing# the work you wanted to do anyway on the generated output.for thing in my_generator():
thing_generated =True
do_work(thing)
Se isso não for bom o suficiente, você ainda poderá executar um teste explícito. Neste ponto, thingconterá o último valor gerado. Se nada foi gerado, será indefinido - a menos que você já tenha definido a variável. Você pode verificar o valor de thing, mas isso é um pouco confiável. Em vez disso, basta definir um sinalizador dentro do bloco e verificar depois:
ifnot thing_generated:print"Avast, ye scurvy dog!"
Esta solução tentará consumir todo o gerador, tornando-o inutilizável para geradores infinitos.
Viktor Stískala
@ ViktorStískala: Eu não entendo o seu ponto. Seria tolo testar se um gerador infinito produzisse algum resultado.
vezult 07/11/13
Queria ressaltar que sua solução pode conter quebra no loop for, porque você não está processando os outros resultados e é inútil gerá-los. range(10000000)é um gerador finito (Python 3), mas você não precisa passar por todos os itens para descobrir se ele gera alguma coisa.
Viktor Stískala
1
@ ViktorStískala: Entendido. No entanto, meu argumento é o seguinte: Geralmente, você realmente deseja operar na saída do gerador. No meu exemplo, se nada for gerado, você já o conhece. Caso contrário, você opera na saída gerada conforme o esperado - "O uso do gerador é o teste". Não há necessidade de testes especiais ou consumo desnecessário da saída do gerador. Eu editei minha resposta para esclarecer isso.
vezult 12/11/13
8
Detesto oferecer uma segunda solução, especialmente uma que eu não usaria, mas, se você tivesse que fazer isso absolutamente e não consumir o gerador, como em outras respostas:
def do_something_with_item(item):print item
empty_marker = object()try:
first_item = my_generator.next()exceptStopIteration:print'The generator was empty'
first_item = empty_marker
if first_item isnot empty_marker:
do_something_with_item(first_item)for item in my_generator:
do_something_with_item(item)
Agora, eu realmente não gosto desta solução, porque acredito que não é assim que os geradores devem ser usados.
Percebo que este post tem 5 anos neste momento, mas o encontrei enquanto procurava uma maneira idiomática de fazer isso e não vi minha solução postada. Assim, para a posteridade:
import itertools
def get_generator():"""
Returns (bool, generator) where bool is true iff the generator is not empty.
"""
gen =(i for i in[0,1,2,3,4])
a, b = itertools.tee(gen)try:
a.next()exceptStopIteration:return(False, b)return(True, b)
Obviamente, como tenho certeza de que muitos comentaristas apontarão, isso é hacky e só funciona em determinadas situações limitadas (onde os geradores são livres de efeitos colaterais, por exemplo). YMMV.
Isso chamará o gengerador apenas uma vez para cada item, portanto os efeitos colaterais não são um problema muito ruim. Mas ele armazenará uma cópia de tudo o que foi extraído do gerador via b, mas não via a, portanto as implicações de memória são semelhantes a apenas executar list(gen)e verificar isso.
Matthias Fripp
Tem dois problemas. 1. Essa ferramenta pode exigir armazenamento auxiliar significativo (dependendo da quantidade de dados temporários que precisam ser armazenados). Em geral, se um iterador usa a maioria ou todos os dados antes de outro iterador iniciar, é mais rápido usar list () em vez de tee (). 2. Os iteradores tee não são seguros para threads. Um RuntimeError pode ser gerado ao usar iteradores simultaneamente retornados pela mesma chamada tee (), mesmo que o iterável original seja seguro para threads.
AJ
3
Desculpe a abordagem óbvia, mas a melhor maneira seria:
for item in my_generator:print item
Agora você detectou que o gerador está vazio enquanto você o está usando. Obviamente, o item nunca será exibido se o gerador estiver vazio.
Isso pode não se encaixar exatamente no seu código, mas é para isso que serve o idioma: iterar, portanto, talvez você possa mudar um pouco sua abordagem ou não usar geradores.
Ou ... o questionador poderia fornecer alguma dica sobre por que alguém tentaria detectar um gerador vazio?
315/09 S.Lott
você quis dizer "nada será exibido porque o gerador está vazio"?
23410 SilentGhost
S.Lott. Concordo. Não vejo o porquê. Mas acho que, mesmo que houvesse um motivo, seria melhor mudar o problema para usar cada item.
27630 Ali Afshar
1
Isso não informa ao programa se o gerador estava vazio.
Ethan Furman
3
Tudo o que você precisa fazer para verificar se um gerador está vazio é tentar obter o próximo resultado. Obviamente, se você não estiver pronto para usar esse resultado, precisará armazená-lo para devolvê-lo mais tarde.
Aqui está uma classe de wrapper que pode ser adicionada a um iterador existente para adicionar um __nonzero__teste, para que você possa ver se o gerador está vazio com um simples if. Provavelmente também pode ser transformado em um decorador.
Isso está indo na direção certa. Ele deve ser modificado para permitir espreitar o máximo que desejar, armazenando quantos resultados forem necessários. Idealmente, isso permitiria empurrar itens arbitrários na cabeça do fluxo. Um iterador empurrável é uma abstração muito útil que costumo usar.
Sfkleach
@sfkleach Não vejo a necessidade de complicar isso por vários olhares antecipados, é bastante útil e responde à pergunta. Mesmo que essa seja uma pergunta antiga, ainda está recebendo uma aparência ocasional; portanto, se você quiser deixar sua própria resposta, alguém poderá achar útil.
Mark Ransom
Mark está certo ao saber que sua solução responde à pergunta, que é o ponto principal. Eu deveria ter formulado melhor. O que eu quis dizer foi que iteradores empurráveis com resposta ilimitada são um idioma que eu achei extremamente útil e a implementação é sem dúvida ainda mais simples. Conforme sugerido, publicarei o código da variante.
sfkleach 7/01
2
Solicitado por Mark Ransom, aqui está uma classe que você pode usar para agrupar qualquer iterador, para que você possa espreitar adiante, enviar valores de volta ao fluxo e verificar se estão vazios. É uma ideia simples, com uma implementação simples, que achei muito útil no passado.
classPushable:def __init__(self, iter):
self.source = iter
self.stored =[]def __iter__(self):return self
def __bool__(self):if self.stored:returnTruetry:
self.stored.append(next(self.source))exceptStopIteration:returnFalsereturnTruedef push(self, value):
self.stored.append(value)def peek(self):if self.stored:return self.stored[-1]
value = next(self.source)
self.stored.append(value)return value
def __next__(self):if self.stored:return self.stored.pop()return next(self.source)
>>> g=(i for i in[])>>> g,empty=is_empty_no_side_effects(g)>>> empty
True>>> g=(i for i in range(10))>>> g,empty=is_empty_no_side_effects(g)>>> empty
False>>> list(g)[0,1,2,3,4,5,6,7,8,9]
>>> gen =(i for i in[])>>> next(gen)Traceback(most recent call last):File"<pyshell#43>", line 1,in<module>
next(gen)StopIteration
No final do gerador StopIterationé gerado, pois no seu caso o fim é alcançado imediatamente, a exceção é gerada.Mas normalmente você não deve verificar a existência do próximo valor.
Outra coisa que você pode fazer é:
>>> gen =(i for i in[])>>>ifnot list(gen):print('empty generator')
O que realmente consome todo o gerador. Infelizmente, não está claro com a pergunta se esse é um comportamento desejável ou indesejável.
315/09 S.Lott
como qualquer outra maneira de "tocar" o gerador, suponho.
SilentGhost 19/03/2009
Sei que este é antiga, mas usando 'list ()' não pode ser a melhor maneira, se a lista gerada não está vazio, mas na verdade grande, então este é desnecessariamente desperdício
Chris_Rands
1
Se você precisar saber antes de usar o gerador, não, não existe uma maneira simples. Se você pode esperar até depois de usar o gerador, existe uma maneira simples:
was_empty =Truefor some_item in some_generator:
was_empty =False
do_something_with(some_item)if was_empty:
handle_already_empty_generator_case()
Simplesmente envolva o gerador com itertools.chain , coloque algo que represente o final do iterável como o segundo iterável e, em seguida, simplesmente verifique isso.
Use em eog = object()vez de assumir que float('-inf')nunca ocorrerá no iterável.
precisa saber é
@bfontaine Boa idéia
smac89
1
No meu caso, eu precisava saber se uma série de geradores foi preenchida antes de passar para uma função que mesclava os itens, ou seja zip(...),. A solução é semelhante, mas diferente o suficiente, da resposta aceita:
def filter_empty(iterables):for iterable in iterables:
itr_has_items, iterable = has_items(iterable)if itr_has_items:yield iterable
def merge_iterables(iterables):
populated_iterables = filter_empty(iterables)for items in zip(*populated_iterables):# Use items for each "slice"
Meu problema específico tem a propriedade de que as iteráveis estão vazias ou têm exatamente o mesmo número de entradas.
Eu encontrei apenas essa solução trabalhando para iterações vazias também.
def is_generator_empty(generator):
a, b = itertools.tee(generator)try:
next(a)exceptStopIteration:returnTrue, b
returnFalse, b
is_empty, generator = is_generator_empty(generator)
Ou, se você não quiser usar a exceção para esta tentativa, use
def is_generator_empty(generator):
a, b = itertools.tee(generator)for item in a:returnFalse, b
returnTrue, b
is_empty, generator = is_generator_empty(generator)
Na solução marcada, não é possível usá-lo para geradores vazios, como
Aqui está minha abordagem simples que eu uso para continuar retornando um iterador enquanto verifica se algo foi produzido, apenas verifico se o loop é executado:
n =0for key, value in iterator:
n+=1yield key, value
if n ==0:print("nothing found in iterator)
break
Aqui está um decorador simples que envolve o gerador, e ele retorna Nenhum se estiver vazio. Isso pode ser útil se o seu código precisar saber se o gerador produzirá alguma coisa antes de passar por ele.
def generator_or_none(func):"""Wrap a generator function, returning None if it's empty. """def inner(*args,**kwargs):# peek at the first item; return None if it doesn't existtry:
next(func(*args,**kwargs))exceptStopIteration:returnNone# return original generator otherwise first item will be missingreturn func(*args,**kwargs)return inner
Uso:
import random
@generator_or_nonedef random_length_generator():for i in range(random.randint(0,10)):yield i
gen = random_length_generator()if gen isNone:print('Generator is empty')
Um exemplo em que isso é útil é no código de modelo - ie jinja2
Isso chama a função do gerador duas vezes, portanto incorrerá no custo de inicialização do gerador duas vezes. Isso pode ser substancial se, por exemplo, a função do gerador for uma consulta ao banco de dados.
Ian Goldby
0
usando o islice, você só precisa verificar a primeira iteração para descobrir se está vazia.
de itertools import islice
def isempty (iterável):
lista de retorno (islice (iterável, 1)) == []
Não podemos usar "any ()" para tudo gerador. Apenas tentei usá-lo com um gerador que contém vários quadros de dados. Recebi esta mensagem "O valor verdadeiro de um DataFrame é ambíguo". em qualquer (my_generator_of_df)
probitaille 8/11
any(generator)funciona quando você sabe que o gerador irá gerar valores que podem ser convertidos para bool- os tipos de dados básicos (por exemplo, int, string) funcionam. any(generator)será Falso quando o gerador estiver vazio, ou quando o gerador tiver apenas valores falsos - por exemplo, se um gerador gerar 0 '' (string vazia) e Falso, ele ainda será Falso. Isso pode ou não ser o comportamento pretendido, contanto que você está ciente de que :)
from cytoolz import peek
from typing importTuple,Iterabledef is_empty_iterator(g:Iterable)->Tuple[Iterable, bool]:try:
_, g = peek(g)return g,FalseexceptStopIteration:return g,True
O iterador retornado por esta função será equivalente ao original transmitido como argumento.
[]
é convenientemente Falsey, então você pode fazer uma verificação se e fazer um comportamento especial para algo ou nada. Os geradores são verdadeiros mesmo que não produzam elementos.glob.iglob("filepattern")
um padrão curinga fornecido pelo usuário e quero avisar o usuário se o padrão não corresponder a nenhum arquivo. Claro que posso solucionar isso de várias maneiras, mas é útil poder testar com clareza se o iterador ficou vazio ou não.Respostas:
A resposta simples para sua pergunta: não, não há uma maneira simples. Existem muitas soluções alternativas.
Realmente não deveria haver uma maneira simples, por causa do que são os geradores: uma maneira de gerar uma sequência de valores sem manter a sequência na memória . Portanto, não há travessia para trás.
Você pode escrever uma função has_next ou talvez até colocá-la em um gerador como um método com um decorador sofisticado, se você quiser.
fonte
Sugestão:
Uso:
fonte
return first, itertools.chain([first], rest)
.def gen(): for pony in range(4): yield None if pony == 2 else pony
None
, mas aumentandoStopIteration
- o resultado da função éNone
. Caso contrário, é uma tupla, o que não éNone
.This method is for backward compatibility only. def next(self): """Return the next message in a one-time iteration.""" if not hasattr(self, '_onetime_keys'): self._onetime_keys = self.iterkeys() while True: try: return self[next(self._onetime_keys)] except StopIteration: return None except KeyError: continue
Uma maneira simples é usar o parâmetro opcional for next () que é usado se o gerador estiver esgotado (ou vazio). Por exemplo:
Edit: Corrigido o problema apontado no comentário de mehtunguh.
fonte
object()
vez declass
para torná-lo uma linha mais curta_exhausted = object()
:;if next(iterable, _exhausted) is _exhausted:
next(generator, None) is not None
Ou substitua,
None
mas o valor que você sabe que não está no seu gerador.Edit : Sim, isso irá pular 1 item no gerador. Freqüentemente, porém, verifico se um gerador está vazio apenas para fins de validação e, na verdade, não o uso. Ou então eu faço algo como:
Ou seja, isso funciona se o seu gerador vier de uma função , como em
generator()
.fonte
None
?A melhor abordagem, IMHO, seria evitar um teste especial. Na maioria das vezes, o uso de um gerador é o teste:
Se isso não for bom o suficiente, você ainda poderá executar um teste explícito. Neste ponto,
thing
conterá o último valor gerado. Se nada foi gerado, será indefinido - a menos que você já tenha definido a variável. Você pode verificar o valor dething
, mas isso é um pouco confiável. Em vez disso, basta definir um sinalizador dentro do bloco e verificar depois:fonte
range(10000000)
é um gerador finito (Python 3), mas você não precisa passar por todos os itens para descobrir se ele gera alguma coisa.Detesto oferecer uma segunda solução, especialmente uma que eu não usaria, mas, se você tivesse que fazer isso absolutamente e não consumir o gerador, como em outras respostas:
Agora, eu realmente não gosto desta solução, porque acredito que não é assim que os geradores devem ser usados.
fonte
Percebo que este post tem 5 anos neste momento, mas o encontrei enquanto procurava uma maneira idiomática de fazer isso e não vi minha solução postada. Assim, para a posteridade:
Obviamente, como tenho certeza de que muitos comentaristas apontarão, isso é hacky e só funciona em determinadas situações limitadas (onde os geradores são livres de efeitos colaterais, por exemplo). YMMV.
fonte
gen
gerador apenas uma vez para cada item, portanto os efeitos colaterais não são um problema muito ruim. Mas ele armazenará uma cópia de tudo o que foi extraído do gerador viab
, mas não viaa
, portanto as implicações de memória são semelhantes a apenas executarlist(gen)
e verificar isso.Desculpe a abordagem óbvia, mas a melhor maneira seria:
Agora você detectou que o gerador está vazio enquanto você o está usando. Obviamente, o item nunca será exibido se o gerador estiver vazio.
Isso pode não se encaixar exatamente no seu código, mas é para isso que serve o idioma: iterar, portanto, talvez você possa mudar um pouco sua abordagem ou não usar geradores.
fonte
Tudo o que você precisa fazer para verificar se um gerador está vazio é tentar obter o próximo resultado. Obviamente, se você não estiver pronto para usar esse resultado, precisará armazená-lo para devolvê-lo mais tarde.
Aqui está uma classe de wrapper que pode ser adicionada a um iterador existente para adicionar um
__nonzero__
teste, para que você possa ver se o gerador está vazio com um simplesif
. Provavelmente também pode ser transformado em um decorador.Veja como você o usaria:
Observe que você pode verificar o vazio a qualquer momento, não apenas no início da iteração.
fonte
Solicitado por Mark Ransom, aqui está uma classe que você pode usar para agrupar qualquer iterador, para que você possa espreitar adiante, enviar valores de volta ao fluxo e verificar se estão vazios. É uma ideia simples, com uma implementação simples, que achei muito útil no passado.
fonte
Apenas caí nessa discussão e percebi que faltava uma resposta muito simples e fácil de ler:
Se não devemos consumir nenhum item, precisamos injetar novamente o primeiro item no gerador:
Exemplo:
fonte
No final do gerador
StopIteration
é gerado, pois no seu caso o fim é alcançado imediatamente, a exceção é gerada.Mas normalmente você não deve verificar a existência do próximo valor.Outra coisa que você pode fazer é:
fonte
Se você precisar saber antes de usar o gerador, não, não existe uma maneira simples. Se você pode esperar até depois de usar o gerador, existe uma maneira simples:
fonte
Simplesmente envolva o gerador com itertools.chain , coloque algo que represente o final do iterável como o segundo iterável e, em seguida, simplesmente verifique isso.
Ex:
Agora tudo o que resta é verificar o valor que acrescentamos ao final do iterável, quando você o ler, isso significará o final
fonte
eog = object()
vez de assumir quefloat('-inf')
nunca ocorrerá no iterável.No meu caso, eu precisava saber se uma série de geradores foi preenchida antes de passar para uma função que mesclava os itens, ou seja
zip(...)
,. A solução é semelhante, mas diferente o suficiente, da resposta aceita:Definição:
Uso:
Meu problema específico tem a propriedade de que as iteráveis estão vazias ou têm exatamente o mesmo número de entradas.
fonte
Eu encontrei apenas essa solução trabalhando para iterações vazias também.
Ou, se você não quiser usar a exceção para esta tentativa, use
Na solução marcada, não é possível usá-lo para geradores vazios, como
fonte
Esta é uma pergunta antiga e respondida, mas como ninguém a mostrou antes, aqui está:
Você pode ler mais aqui
fonte
Aqui está minha abordagem simples que eu uso para continuar retornando um iterador enquanto verifica se algo foi produzido, apenas verifico se o loop é executado:
fonte
Aqui está um decorador simples que envolve o gerador, e ele retorna Nenhum se estiver vazio. Isso pode ser útil se o seu código precisar saber se o gerador produzirá alguma coisa antes de passar por ele.
Uso:
Um exemplo em que isso é útil é no código de modelo - ie jinja2
fonte
usando o islice, você só precisa verificar a primeira iteração para descobrir se está vazia.
fonte
Que tal usar any ()? Eu uso com geradores e está funcionando bem. Aqui tem um cara explicando um pouco sobre isso
fonte
any(generator)
funciona quando você sabe que o gerador irá gerar valores que podem ser convertidos parabool
- os tipos de dados básicos (por exemplo, int, string) funcionam.any(generator)
será Falso quando o gerador estiver vazio, ou quando o gerador tiver apenas valores falsos - por exemplo, se um gerador gerar 0 '' (string vazia) e Falso, ele ainda será Falso. Isso pode ou não ser o comportamento pretendido, contanto que você está ciente de que :)Use a função de espiar no cytoolz.
O iterador retornado por esta função será equivalente ao original transmitido como argumento.
fonte
Eu o resolvi usando a função soma. Veja abaixo um exemplo que usei com glob.iglob (que retorna um gerador).
* Isso provavelmente não funcionará para geradores ENORME, mas deve funcionar bem para listas menores
fonte