Devo preferir geradores Python a listas?

8

Os iteradores Python podem ser muito eficientes na memória. Devo sempre preferir usar geradores em vez de apenas listas? Em que situações devo preferir uma matriz simples?

Por exemplo, em vez disso:

emails = [user.email for user in users]

devo preferir isso ?:

emails = (user.email for user in users)

Nota : quero dizer 'geradores', não 'iteradores'.

nicholaides
fonte
Não está claro de que ajuda você precisa . Esclareça seu problema específico ou forneça detalhes adicionais para destacar exatamente o que você precisa. Como está escrito atualmente, é difícil dizer qual problema você está tentando resolver ou que aspecto de sua abordagem precisa ser corrigido ou explicado. Consulte apágina Como pedir ajuda para esclarecer esta questão.
Gnat
@gnat a pergunta seria reformulada como "quando devo usar iteradores ou listas em python?" Fique bem?
Florian Margaine 17/02/2015
@FlorianMargaine que iria colocá-lo em risco de ser fechado como muito amplo Receio
mosquito
2
@FlorianMargaine Isso seria um bom começo, mas ainda é uma pergunta fraca. Onde está a pesquisa do autor? Certamente ele pode pensar em algumas diferenças. Pedir para enumerar todas as situações em que você pode querer usar uma ou outra não é tão bom.
Doval
2
+1 Pode ser uma pergunta pouco clara, mas quando você está apenas aprendendo a usar essas estruturas, suas perguntas serão vagamente formadas e formuladas. Eu aprendi muito com as respostas.
Racheet

Respostas:

7

A principal desvantagem dos geradores é que eles só podem ser atravessados ​​em uma direção. Não há como voltar a um valor anterior. Você também não pode compartilhá-los. Existem muitos casos em que isso pode ser facilmente explicado, ou mesmo onde é preferível, mas também há muitos casos em que não é. Classificação, por exemplo.

É por isso que muitas vezes você vê geradores usados ​​para os estágios iniciais de processamento de uma grande quantidade de dados; depois, uma vez filtrados em um subconjunto e mapeados em um bom formato, são colocados em uma estrutura de dados concreta duradoura para uso adicional. Dessa forma, você não gasta a alocação de memória, os erros de cache e a coleta de lixo em grandes matrizes intermediárias que imediatamente jogará fora.

Karl Bielefeldt
fonte
3

Você confundiu iteradores com geradores.

Seu primeiro exemplo é uma expressão de iterador de lista, enquanto o segundo é uma expressão de gerador. A principal diferença é que o gerador cria cada membro da coleção fornecida preguiçosamente (conforme necessário) e não ansiosamente (ao mesmo tempo, se necessário ou não). Você pode definir seus próprios geradores usando rendimento em vez de retorno.

Quanto ao uso, você deseja um iterador quando precisar da lista (ou dicionário ou qualquer outra coisa) para algo por si só. Você usaria um gerador quando a coleta é incidental para o produto final. Por exemplo, você pode usar um gerador para obter uma lista de números que atendem a alguns critérios de outros critérios. Você não se importa com a lista original, apenas com os membros que se enquadram nos critérios. Assim, você usa um gerador para obter apenas esses números.

Um exemplo mais concreto seria encontrar os ângulos dos triângulos cujos lados têm um determinado comprimento. Não queremos todos os pobres, deformados triângulos fracassados, apenas os triângulos fortes e saudáveis ​​de sucesso. Assim, usaríamos um gerador.

Esta postagem Stack Overflow entra em mais detalhes.

Engenheiro Mundial
fonte