[Tutor] List Comprehension Syntax

Peter Otten __peter__ at web.de
Sun Dec 23 12:53:08 CET 2012


Mario Cacciatore wrote:

> Hey everyone,
> 
> I am having a very hard time understanding the list comprehension syntax.
> I've followed the docs and could use some guidance from the fine folks
> here to supplement my findings. If someone wouldn't mind replying back
> with an example or two, with some explanation of each part I'd appreciate
> it.

Consider

[c.lower() + x % 3 * c for x in range(10) if x not in [7,8] for c in "aBcDE" 
if c.isupper() if c != "B"]

That looks complex! So let's take it apart. Here's the cheat-sheet:

result = [expr(x) for x in items]

is equivalent to a for-loop:

result = []
for x in items:
    result.append(expr(x))

The expression on the left of the list-comp moves into the (innermost if 
there is mor than one) loop.

result = [expr(x) for x in items if cond(x)]

is equivalent to

result = []
for x in items:
    if cond(x):
        result.append(expr(x))

You can add an arbitrary number of conditions:

result = [expr(x) for x in items if cond1(x) if cond2(x) if cond3(x)]

is equivalent to

result = []
for x in items:
    if cond1(x):
        if cond2(x):
            if cond3(x):
                result.append(expr(x))

You can also have multiple 'for' clauses:

result = [expr(x, y, z) for x in items1 for y in items2 for z in items3]

is equivalent to

result = []
for x in items1:
    for y in items2:
        for z in items3:
            result.append(expr(x, y, z))

Now back to our initial example. Let's reformat it a bit

result = [
    c.lower() + x % 3 * c  # that's expr(x, c)
    for x in range(10) 
        if x not in [7,8] 
            for c in "aBcDE" 
                if c.isupper() 
                    if c != "B"
]

That looks quite similar to

result = []
for x in range(10) :
    if x not in [7,8]:
        for c in "aBcDE":
            if c.isupper():
                if c != "B":
                    result.append(c.lower() + x % 3 * c)

Whenever you encounter a list comprehension you don't understand immediately 
you can easily translate it into for-loops and if-statements, either by 
reformatting in an editor or in your mind. Similarly you can convert for-
loops appending to a list into a list comprehension. Can you spell

result_loop = []
for x in range(10):
    for y in range(10):
        if (x + y) % 2:
            result_loop.append((x, y))

as a list-comp? Copy the above twice and apply the reverse reformatting 
trick to the second copy.

result_listcomp = [...] # your code
assert result_loop == result_listcomp, "Something went wrong, try again"
print("success")

If you run the script it should print 'success'.




More information about the Tutor mailing list