Order of iterators may seem counter-intuitive

Take for example: [str(x) for i in range(3) for x in foo(i)]

Let's decompose it:

def foo(i): return i, i + 0.5 [str(x) for i in range(3) for x in foo(i) ] # is same as for i in range(3): for x in foo(i): yield str(x)

#python #worklog

Follow

@continue There are two differences:

1) The second version is not legal out of context; you can only use yield inside a function definition.

2) Even if the second is corrected to

def g():
for i in range(3):
for x in foo(i):
yield str(x)

g()

then you get a generator, not a list. It would be equivalent to the first version if you changed the last line to:

list(g())

A more direct translation might be:

result = []
for i in range(3):
for x in foo(i):
result.append(str(x))

result

Your larger point, that the order of the for loops is the same whether you use lists comprehensions or actual nested loops, still holds.

Personally, I avoid this sort of nested comprehension because of just this sort of confusion. It's also counterintuitive because you can't "unpack" it in the usual way by adding brackets.

[str(x) for i in range(3) for x in foo(i)]

does not produce the same result as:

[[str(x) for i in range(3)] for x in foo(i)]

@peterdrake

This is interesting, thanks.

I was initially confused by the order of iteration over two for.

Sign in to participate in the conversation
CleverLibre Social

CleverLibre Social is an inclusive social instance for open discussion, learning, and community.
All cultures welcome.
Hate speech and harassment strictly forbidden.