A melhor fonte de informações é o tutorial oficial do Python sobre compreensão de listas . As compreensões de lista são quase as mesmas que os loops for (certamente qualquer compreensão de lista pode ser escrita como um loop for), mas geralmente são mais rápidas do que usar um loop for.
Veja esta compreensão de lista mais longa do tutorial (a if
parte filtra a compreensão, apenas as partes que passam na instrução if são passadas para a parte final da compreensão de lista (aqui (x,y)
):
>>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
É exatamente igual a este loop for aninhado (e, como diz o tutorial, observe como a ordem de for e if são as mesmas).
>>> combs = []
>>> for x in [1,2,3]:
... for y in [3,1,4]:
... if x != y:
... combs.append((x, y))
...
>>> combs
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
A principal diferença entre uma compreensão de lista e um loop for é que a parte final do loop for (onde você faz algo) vem no início e não no final.
Para suas perguntas:
Que tipo de objeto deve ser para usar esta estrutura de loop for?
Um iterável . Qualquer objeto que pode gerar um conjunto (finito) de elementos. Isso inclui qualquer recipiente, listas, conjuntos, geradores, etc.
Qual é a ordem em que i e j são atribuídos aos elementos no objeto?
Eles são atribuídos exatamente na mesma ordem em que são gerados a partir de cada lista, como se estivessem em um loop for aninhado (para sua primeira compreensão, você obteria 1 elemento para i, então, cada valor de j, 2º elemento em i, então, cada valor de j, etc.)
Pode ser simulado por uma estrutura diferente de loop for?
Sim, já mostrado acima.
Este loop for pode ser aninhado com uma estrutura for loop semelhante ou diferente? E como ficaria?
Claro, mas não é uma boa ideia. Aqui, por exemplo, fornece uma lista de listas de personagens:
[[ch for ch in word] for word in ("apple", "banana", "pear", "the", "hello")]