[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