Eu tenho uma função de gerador como a seguinte:
def myfunct():
...
yield result
A maneira usual de chamar essa função seria:
for r in myfunct():
dostuff(r)
Minha pergunta, existe uma maneira de obter apenas um elemento do gerador sempre que eu quiser? Por exemplo, eu gostaria de fazer algo como:
while True:
...
if something:
my_element = pick_just_one_element(myfunct())
dostuff(my_element)
...
python
iterator
generator
python-2.x
Alexandros
fonte
fonte
next(gen, default)
também pode ser usado para evitar aStopIteration
exceção. Por exemplo,next(g, None)
para um gerador de strings, produzirá uma string ou None após a conclusão da iteração.next(g)
,. Isso chamará internamenteg.__next__()
, mas você realmente não precisa se preocupar com isso, assim como geralmente não se importa com o quelen(a)
chama internamentea.__len__()
.g.next()
estág.__next__()
em py3k. O builtnext(iterator)
-in existe desde o Python 2.6, e é o que deve ser usado em todos os novos códigos do Python, e é trivial implementar de novo se você precisar dar suporte ao py <= 2.5.Para escolher apenas um elemento de um gerador, use
break
em umafor
declaração oulist(itertools.islice(gen, 1))
De acordo com o seu exemplo (literalmente), você pode fazer algo como:
Se você deseja " obter apenas um elemento do gerador [uma vez gerado] sempre que eu quiser " (suponho que 50% seja a intenção original e a intenção mais comum), então:
Dessa maneira, o uso explícito de
generator.next()
pode ser evitado e o tratamento de final de entrada não requerStopIteration
tratamento de exceção (enigmático) ou comparações extras de valores padrão.A seção
else:
defor
declaração é necessária apenas se você quiser fazer algo especial no caso de fim de gerador.Nota sobre
next()
/.next()
:No Python3, o
.next()
método foi renomeado.__next__()
por um bom motivo: é considerado de baixo nível (PEP 3114). Antes do Python 2.6, a função internanext()
não existia. E foi discutido até a mudançanext()
para ooperator
módulo (o que seria sensato), devido à sua rara necessidade e inflação questionável de nomes internos.Usar
next()
sem padrão ainda é uma prática de nível muito baixo - lançar o enigmáticoStopIteration
como um raio do nada no código normal do aplicativo abertamente. E o usonext()
com o sentinel padrão - que melhor deve ser a única opção para uma entradanext()
diretabuiltins
- é limitado e geralmente dá motivo a lógicas / legibilidade não-pitonais estranhas.Conclusão: Usar next () deve ser muito raro - como usar funções do
operator
módulo. Usandofor x in iterator
,islice
,list(iterator)
e outras funções aceitar um iterador perfeitamente é a maneira natural de usar iteradores no nível de aplicação - e bastante sempre possível.next()
é de baixo nível, um conceito extra, não óbvio - como mostra a pergunta deste tópico. Enquanto, por exemplo, o usobreak
emfor
é convencional.fonte
mySeq.head
?Não acredito que exista uma maneira conveniente de recuperar um valor arbitrário de um gerador. O gerador fornecerá um método next () para se movimentar, mas a sequência completa não é produzida imediatamente para economizar memória. Essa é a diferença funcional entre um gerador e uma lista.
fonte
Para aqueles que estão pesquisando essas respostas para obter um exemplo completo de trabalho para Python3 ... bem, aqui está:
Isso gera:
fonte
Gerador é uma função que produz um iterador. Portanto, depois de ter a instância do iterador, use next () para buscar o próximo item do iterador. Como exemplo, use a função next () para buscar o primeiro item e, posteriormente, use
for in
para processar os itens restantes:fonte
certifique-se de capturar a exceção lançada após a captura do último elemento
fonte
Acredito que a única maneira é obter uma lista do iterador e obter o elemento que você deseja dessa lista.
fonte
myfunct()
gera um grande número de valores), pois você pode usar a função internanext
para obter o próximo valor gerado.