No shell Python, se eu inserir uma compreensão de lista, como:
>>> [x for x in string.letters if x in [y for y in "BigMan on campus"]]
Obtenho um resultado bem impresso:
['a', 'c', 'g', 'i', 'm', 'n', 'o', 'p', 's', 'u', 'B', 'M']
O mesmo para uma compreensão de dicionário:
>>> {x:x*2 for x in range(1,10)}
{1: 2, 2: 4, 3: 6, 4: 8, 5: 10, 6: 12, 7: 14, 8: 16, 9: 18}
Se eu inserir uma expressão geradora, não recebo uma resposta tão amigável:
>>> (x for x in string.letters if x in (y for y in "BigMan on campus"))
<generator object <genexpr> at 0x1004a0be0>
Eu sei que posso fazer isso:
>>> for i in _: print i,
a c g i m n o p s u B M
Além disso (ou escrevendo uma função auxiliar), posso avaliar e imprimir facilmente esse objeto gerador no shell interativo?
generator object
enquanto construo interativamente uma compreensão no prompt interativo. Ligarlist(_)
faz isso. O que eu fiz foi usar compreensões de lista e transformá-las em genexp em código maior. Eles podem falhar em tempo de execução de maneiras que as compreensões de lista não.list()
, e imprimi-los.Respostas:
Resposta rápida:
Fazer em
list()
torno de uma expressão geradora é (quase) exatamente equivalente a ter[]
colchetes ao redor dela. Então sim, você pode fazerMas você também pode fazer
Sim, isso transformará a expressão do gerador em uma compreensão de lista. É a mesma coisa e lista de chamadas () nela. Portanto, a maneira de transformar uma expressão geradora em uma lista é colocá-la entre colchetes.
Explicação detalhada:
Uma expressão geradora é uma expressão "nua"
for
. Igual a:Agora, você não pode colocar isso em uma linha por si só, você obterá um erro de sintaxe. Mas você pode colocar parênteses ao redor.
Isso às vezes é chamado de compreensão de gerador, embora eu ache que o nome oficial ainda seja expressão de gerador, não há realmente nenhuma diferença, os parênteses estão lá apenas para tornar a sintaxe válida. Você não precisa deles se estiver transmitindo-os como o único parâmetro para uma função, por exemplo:
Basicamente, todas as outras compreensões disponíveis no Python 3 e Python 2.7 são apenas açúcar sintático em torno de uma expressão geradora. Definir compreensões:
Compreensões de ditado:
E listar compreensões em Python 3:
No Python 2, as compreensões de lista não são apenas açúcar sintático. Mas a única diferença é que x no Python 2 vazará para o namespace.
Enquanto estiver no Python 3, você obterá
Isso significa que a melhor maneira de obter uma boa impressão do conteúdo de sua expressão geradora em Python é fazer uma lista de compreensão a partir dela! No entanto, isso obviamente não funcionará se você já tiver um objeto gerador. Isso apenas fará uma lista de um gerador:
Nesse caso, você precisará ligar para
list()
:Embora isso funcione, mas é meio estúpido:
fonte
list( generator-expression )
não está imprimindo a expressão do gerador; ele está gerando uma lista (e, em seguida, imprimindo-a em um shell interativo). Em vez de gerar uma lista, no Python 3, você pode dividir a expressão geradora em uma instrução de impressão. Ie)print(*(generator-expression))
. Isso imprime os elementos sem vírgulas e sem colchetes no início e no final.Ao contrário de uma lista ou dicionário, um gerador pode ser infinito. Fazer isso não funcionaria:
Além disso, a leitura de um gerador o altera, portanto não há uma maneira perfeita de visualizá-lo. Para ver uma amostra da saída do gerador, você poderia fazer
fonte
[next(g1) for i in range(10)]
em Python 3.Você pode simplesmente envolver a expressão em uma chamada para
list
:fonte
Ou você pode sempre
map
usar um iterador, sem a necessidade de construir uma lista intermediária:fonte
fonte