On 23/12/12 18:48, 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.
If you did mathematics in high school, you may remember set-builder notation:
http://en.wikipedia.org/wiki/Set-builder_notation
There are a number of variations of this notation, depending on how formal
you want to be. For example:
{3x+1 ∀ x ∈ {1, 2, 3}}
This says:
"build the set of values 3 times x plus 1, for all x values that are elements
of the set {1, 2, 3}"
and it would produce the values:
x=1 -> 3*1 + 1
x=2 -> 3*2 + 1
x=3 -> 3*3 + 1}
giving the final set {4, 7, 10}
Python uses similar notation, except based on English words instead of
mathematical symbols. In Python, we generally use lists or tuples, not sets,
so the list comprehension would be:
[3*x + 1 for x in (1, 2, 3)]
We can pull this apart to see what each part does.
[ ]
The square brackets build a list.
3*x + 1
This is the list comprehension expression. It is evaluated each time
the list comp goes through the loop.
for x in (1, 2, 3)
This sets up the list comprehension loop, and defines the loop
variable, just like a for-loop. The tuple (1, 2, 3) is the loop
sequence, x takes each value from this in turn.
So this list comprehension is equivalent to this for-loop:
tmp = []
for x in (1, 2, 3):
tmp.append(3*x + 1)
except that you don't need to define a temporary list to accumulate the
results, the list comprehension does that for you.
List comprehensions can be more complicated. They can also take one or
more "if" clause:
[2*n for n in range(10) if n%2 == 1]
is equivalent to this for-loop:
tmp = []
for n in range(10):
if n%2 == 1:
tmp.append(2*n)
and so it will produce the list:
[2, 6, 10, 14, 18]
Naturally, you can use any sequence or iterable in the for-loop
part of list comps:
myname = "Quentin"
[c for c in myname if c.lower() != "q" if c.upper() != "T"]
will give
['u', 'e', 'i', 'n']
The sequence can even be another list comprehension:
[y+1 for y in [2*x for x in (1, 2, 3)] if y < 5]
gives [3, 5], and is equivalent to this pair of loops:
tmp1 = []
tmp2 = []
for x in (1, 2, 3):
tmp1.append(2*x)
for y in tmp1:
if y < 5:
tmp2.append(y+1)
List comps can also take multiple loops:
[(a, b) for a in range(3) for b in range(3)]
gives this result:
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
and is equivalent to this nested loop:
tmp = []
for a in range(3):
for b in range(3):
tmp.append( (a, b) )
List comprehensions are powerful and compact, but because they are so compact,
they can also be hard to read. Resist the temptation to write every for-loop
as a list comprehension! Keep your list comps simple, and you will not regret
it. Nobody has ever said, "I wish my list comprehensions were more complicated
and hard to read!"
--
Steven
_______________________________________________
Tutor maillist - Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor