There's nothing magic about nested list comprehensions. I think you're simply not seeing their simplicity yet!
This:
# X A B C
a = [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
is simply syntactic sugar for:
__tmp = []
for x in [1,2,3]: # A
for y in [3,1,4]: # B
if x != y: # C
__tmp.append((x, y)) # X
a = __tmp
So you take the for ... in ...
parts and re-assemble them as nested for
loops. You then take the if
s and nest it in the corresponding for
loop; finally, you take the first part ((x, y)
in this case) and you nest at the deepest part of the nested for
structure.
This works out fine also when if
s appear at multiple "stages" in a list comprehension, for example:
# X A B C D
a = [(x, y) for x in [1,2,3] if x >= 2 for y in [3,1,4] if x != y]
translates (desugars) to:
__tmp = []
for x in [1,2,3]: # A
if x >= 2: # B
for y in [3,1,4]: # C
if x != y: # D
__tmp.append((x, y)) # X
a = __tmp
So again... it's just exactly the same as the comprehension with colons interspersed between the parts, and the inner part brought right in the front. The order of the A B C D ...
part is always the same and never changed; it's only the X
part that's moved from the back to the front.