質問

I have been recently introduced to list comprehensions, however, I am not certain I understand them completely.

So, I did a quick search through the docs and google. I found the docs section over data structures.

https://docs.python.org/2/tutorial/datastructures.html

While that gives me an idea with how they work, call me strange, I want to have a more mature understanding of how they operate.

Here is an example from the docs:

>>>[(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)]

Correct me if I am wrong, but this is how I understand how the list is evaluating.

  • It looks like the list comprehension evaluates from left to right.
  • This comprehension introduces X and Y.
  • Then defines X and Y by the lists and evaluates based on position in list as well as the if condition.
  • Due to X being assigned as the first variable, like the outside of a nested for loop, it is called first and iterated against Y's list.
  • The if condition makes it so the comprehension only produces pairs that are not similar as X iterates through Y's list.

Please correct me if my understanding is incorrect. I welcome more complex examples for comprehensions.

役に立ちましたか?

解決

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 ifs 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 ifs 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.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top