No Python, você pode ter vários iteradores em uma compreensão de lista, como
[(x,y) for x in a for y in b]
para algumas sequências adequadas a e b. Estou ciente da semântica de loop aninhado das compreensões de lista do Python.
Minha pergunta é: um iterador na compreensão pode se referir ao outro? Em outras palavras: eu poderia ter algo parecido com isto:
[x for x in a for a in b]
onde o valor atual do loop externo é o iterador do interno?
Como exemplo, se eu tiver uma lista aninhada:
a=[[1,2],[3,4]]
qual seria a expressão de compreensão da lista para alcançar esse resultado:
[1,2,3,4]
?? (Por favor, liste apenas as respostas de compreensão, pois é isso que eu quero descobrir).
fonte
[x for b in a for x in b]
Isso sempre causou problemas em python. Essa sintaxe é muito atrasada. A forma geral dex for x in y
sempre tem a variável diretamente após o for, alimenta a expressão à esquerda do for. Assim que você faz uma dupla compreensão, sua variável iterada mais recentemente fica subitamente tão "longe". É estranho, e não lê naturalmenteEspero que isso ajude outra pessoa, pois
a,b,x,y
não tem muito significado para mim! Suponha que você tenha um texto cheio de frases e queira uma variedade de palavras.Eu gosto de pensar na compreensão da lista como esticar o código horizontalmente.
Tente dividi-lo em:
Exemplo:
Isso também funciona para geradores
fonte
Puxa, acho que encontrei a resposta: não estava cuidando o suficiente sobre qual loop é interno e qual é externo. A compreensão da lista deve ser como:
para obter o resultado desejado e sim, um valor atual pode ser o iterador para o próximo loop.
fonte
A ordem dos iteradores pode parecer contra-intuitiva.
Considere por exemplo:
[str(x) for i in range(3) for x in foo(i)]
Vamos decompor:
fonte
[(output in loop 2) (loop 1) (loop 2)]
com(loop 1) = for i in range(3)
e(loop 2) = for x in foo(i):
e(output in loop 2) = str(x)
.ThomasH já adicionou uma boa resposta, mas quero mostrar o que acontece:
Eu acho que Python analisa a compreensão da lista da esquerda para a direita. Isso significa que o primeiro
for
loop que ocorrer será executado primeiro.O segundo "problema" disso é que
b
"vaza" da compreensão da lista. Após a primeira compreensão bem sucedida da listab == [3, 4]
.fonte
x = 'hello';
[x for x in xrange(1,5)];
print x # x is now 4
Se você deseja manter a matriz multidimensional, deve-se aninhar os colchetes da matriz. veja o exemplo abaixo, onde um é adicionado a cada elemento.
fonte
Essa técnica de memória me ajuda muito:
[ <RETURNED_VALUE> <OUTER_LOOP1> <INNER_LOOP2> <INNER_LOOP3> ... <OPTIONAL_IF> ]
E agora você pode pensar em R egressar + O uter de circuito como o único R ight O rder
Sabendo acima, a ordem na lista abrangente, mesmo para três loops, parece fácil:
porque o acima é apenas um:
para iterar uma lista / estrutura aninhada, technic é o mesmo: para
a
a pergunta:um para o outro nível aninhado
e assim por diante
fonte
Eu sinto que isso é mais fácil de entender
fonte
Além disso, você pode usar exatamente a mesma variável para o membro da lista de entrada atualmente acessada e para o elemento dentro desse membro. No entanto, isso pode até torná-lo mais incompreensível (lista).
Primeiro
for x in input
é avaliado, levando a uma lista de membros da entrada; em seguida, o Python percorre a segunda parte,for x in x
durante a qual o valor x é sobrescrito pelo elemento atual que está acessando, depois o primeirox
define o que queremos retornar.fonte
Essa função flatten_nlevel chama recursivamente a lista aninhada1 para ocultar um nível. Experimente isso
resultado:
fonte
flatten_nlevel(sublist, flat_list)
, né ?!