15.12.2022 Views

Python Eficaz

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

elas retornam um iterador. Em cada chamada à função nativa next, o iterador

avançará o gerador para a próxima expressão do yield. Cada valor passado ao

yield pelo gerador será devolvido pelo iterador ao chamador.

No exemplo a seguir, a função geradora definida produz os mesmos resultados

de antes:

def index_words_iter(text):

if text:

yield 0

for index, letter in enumerate(text):

if letter == ' ':

yield index + 1

O código é muito mais fácil de ler em comparação com o anterior, porque todas

as interações com a lista resultante foram eliminadas. Os resultados, em vez

disso, são passados a expressões yield. O iterador retornado pela chamada ao

gerador pode facilmente ser convertido em uma lista, basta passá-lo como

argumento da função nativa list (consulte o Item 9: “Considere usar expressões

geradoras em abrangências muito grandes” para saber como isso funciona).

result = list(index_words_iter(address))

O segundo problema com index_words é que ele precisa ter todos os resultados

de antemão para poder criar a lista e devolvê-la ao chamador. Para dados de

entrada de grande monta, seu programa pode esgotar a memória e travar. Em

contrapartida, a versão que emprega geradores pode facilmente ser adaptada para

aceitar dados de entrada de tamanho arbitrário.

No exemplo a seguir, definimos um gerador que obtém dados de um arquivo de

entrada, uma linha por vez, e devolve na saída uma palavra por vez. A memória

de trabalho desta função está limitada ao tamanho máximo de uma linha de

entrada.

def index_file(handle):

offset = 0

for line in handle:

if line:

yield offset

for letter in line:

www.full-ebook.com

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!