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'.
python
performance
nicholaides
fonte
fonte
Respostas:
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.
fonte
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.
fonte