Os geradores são um dos recursos mais atraentes da linguagem Python. Os geradores são, na verdade, um iterador especial, mas esse iterador é mais elegante. Ele não precisa mais definir os métodos __iter__() e __next__() na classe como acima. Ele só precisa declarar uma palavra-chave yield na função. Portanto, um gerador é um tipo especial de iterador (o inverso não é verdadeiro), portanto, qualquer gerador também gera valores no modo de carregamento lento. Um exemplo de uso de um gerador para implementar a sequência de Fibonacci é:
def fib(máx.):
n, a, b = 0, 0, 1
enquanto n <máx:
rendimento b
uma, b = b, uma + b
n = n + 1
para eu em fib(10):
imprimir (eu)
(1) Objeto gerador
Simplificando, um gerador é uma função que usa a palavra-chave yield:
contagem regressiva def (n):
print('início da contagem regressiva')
enquanto n > 0:
rendimento m
n-= 1
imprimir('Concluído!')
imprimir(contagem regressiva) #
geração = contagem regressiva(5)
imprimir(gen) #
# O objeto gerador também é um objeto iterador. Ele deve ter iter e next, que são encapsulados pela palavra-chave yield quando a função é chamada. Não há necessidade de defini-lo você mesmo.
# imprimir(gen.__iter__())
# imprimir(gen.__next__())
# imprimir(gen.__next__())
# imprimir(gen.__next__())
para eu em gen:
imprimir (eu)
Análise: Apenas um objeto gerador será retornado quando a função geradora for chamada. Somente quando o objeto gerador chamar o método __next__ a execução do código do corpo da função será acionada. Ele irá parar até que a palavra-chave rendimento seja encontrada, e o valor após rendimento será retornado como o valor de retorno. Portanto, rendimento é semelhante à função de return, mas diferente de return. Sim, return retorna e a função termina; enquanto yield suspende o status da função e espera que o objeto gerador chame o método __next__ novamente. A função continua a ser executada a partir da primeira instrução após a posição suspensa até encontrar rendimento novamente e retornar. O valor subsequente; se o método __next__ for chamado continuamente e o corpo da função for inserido pela última vez, e o código a ser executado não tiver mais rendimento, um erro de exceção de iteração será relatado.
Além disso, em comparação com os iteradores, os objetos geradores possuem vários outros métodos:
(1) Um método de fechamento integrado é usado para se fechar
(2) Um método de envio integrado, que entra no gerador, é semelhante ao próximo, mas tem uma função adicional de passar valores para a variável de rendimento.
Resumo das funções do rendimento:
(1) Encapsular o iter e os próximos métodos (2) Ao executar uma função, o rendimento é retornado e o valor subsequente é retornado. Ao contrário do retorno, o rendimento pode retornar vários valores (3) O status da função suspensa é encontrado quando o próximo método for chamado da próxima vez.A execução continua na posição de pausa correspondente.
expressão geradora
Existem duas maneiras de criar um objeto gerador: uma é criando a palavra-chave yield na função. A outra é a expressão geradora, que é um formato de sintaxe semelhante à geração de lista aprendida em tipos de dados, exceto que [] é substituído por (), ou seja:
(expressão para item em condição if iterável)
Ao contrário das expressões de geração de lista, que em última análise retornam um resultado de lista, as expressões geradoras, como o nome indica, retornam um objeto gerador, como:
>>> [x*x for x in range(4)] # Compreensão da lista
[0, 1, 4, 9]
>>> gen=(x*x para x no intervalo(4))
>>> geração
em 0x101be0ba0>
Quando os valores são necessários, os valores são calculados um por um chamando o próximo método ou loop for:
>>> próximo(geração)
0
>>> próximo(geração)
1
>>> próximo(geração)
4
>>> próximo(geração)
9
>>> próximo(geração)
Traceback (última chamada mais recente):
Arquivo "", linha 1, em
PararIteração
#----------------para loop---------------------------------
>>> gen=(x*x para x no intervalo(4))
>>> para i na geração:
... imprimir (eu)
...
0
1
4
9
Objetos iteráveis, iteradores, relacionamentos geradores
Questões de entrevista
def adição(s, x):
retornar s + x
def geração():
para i no intervalo (4):
rendimento eu
base = geração()
para n em [1, 10]:
base = (adicionar (i, n) para i na base)
imprimir(lista(base))