472,956 Members | 2,602 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,956 software developers and data experts.

List Comprehension question

I recently stumbled over List Comprehension while reading the
Python Cookbook. I have not kept up with the What's New
sections in the online docs. :)

Anyway, I thought I was following the discussions of List
Comprehension (LC) until I got to Recipe 1.16. In this recipe
we have the following:

arr = [[1,2,3], [4,5,6], [7,8,9], [10,11,12]]
print [[r[col] for r in arr] for col in range(len(arr[0]))]
-> [[1, 4, 7, 10], [2, 5, 8, 11], [3, 6, 9, 12]]

For all the previous LC examples (and in the What's New
writeup for 2.0) it was stated (or implied) that code of the form:

[ expression for expr in sequence1
for expr2 in sequence2 ...
for exprN in sequenceN
if condition ]

was equivalent to:

for expr1 in sequence1:
for expr2 in sequence2:
...
for exprN in sequenceN:
if (condition):
# Append the value of
# the expression to the
# resulting list.

I thought I understood this until I got to the above recipe. Here
it looks like the order of evaluation is reversed. That is, instead
of translating to:

for r[col] in arr:
for col in range(len(arr[0])):
...

we actually have

for col in range(len(arr[0])):
for r[col] in arr:
...

And all of this due to a placement of '[ ... ]' around the 'inner'
loop.

The reference documentation doesn't explain this either. The grammar
page on List Displays doesn't seem to give any insight.

While I don't really understand it I may have some kind of rationale.
Please let me know if this is correct.

The print... command is a LC with a single expression and a single 'for'
construct. The expression, itself, is also a LC. When the command is
executed 'col' is set to 0 (the first value in the range) and this is
'passed' to the expression for evaluation. This evaluation results in
a list generated by the 'inner' LC which iterates over each row in the
array and, therefore, generates the list: [1, 4, 7, 10].

The next step is to go back to 'col' and extract the next value (1) and
generate the next list, etc.

Well, hmmmmm. OK. Maybe I do understand it. It just wasn't apparent
at first.

Am I close, or did I guess wrong?

Mark

Jul 18 '05 #1
1 1267
Mark Elston wrote in message ...
Anyway, I thought I was following the discussions of List
Comprehension (LC) until I got to Recipe 1.16. In this recipe
we have the following:

arr = [[1,2,3], [4,5,6], [7,8,9], [10,11,12]]
print [[r[col] for r in arr] for col in range(len(arr[0]))]
-> [[1, 4, 7, 10], [2, 5, 8, 11], [3, 6, 9, 12]]
All the second line is saying, is, for every pass of the innermost (here,
rightmost) for-loop, execute this list comprehension: [r[col] for r in arr].

Same as:

res = []
for col in range(3):
res.append([r[col] for r in arr])

Unrolling a bit more:

res = []
for col in range(3):
innerres = []
for r in arr:
innerres.append(r[col])
res.append(innerres)

Note this is NOT the same as [r[col] for col in range(3) for r in arr]!

res = []
for col in range(3):
for r in arr:
res.append(r[col])

-> [1, 4, 7, 10, 2, 5, 8, 11, 3, 6, 9, 12]
See? It's flattened, because the list comp's expression evaluates to an
integer instead of a list.
I thought I understood this until I got to the above recipe. Here
it looks like the order of evaluation is reversed. That is, instead
of translating to:

for r[col] in arr:
for col in range(len(arr[0])):
...

we actually have

for col in range(len(arr[0])):
for r[col] in arr:
...
Nope. See above.
While I don't really understand it I may have some kind of rationale.
Please let me know if this is correct.
You're thinking too much. :)
The expression, itself, is also a LC.
This is the part that's causing you confusion. This is a nested list comp:
for every iteration in the outer list comp, execute the expression. The
fact that the expression happens to be a list comp itself just means that
the outer list comp will append a new list on each pass.

Wrap the inner list comp in a function call and it will make sense to you:

def innercomp(col):
return [r[col] for r in arr]

[innercomp(col) for col in range(3)]

-> [[1, 4, 7, 10], [2, 5, 8, 11], [3, 6, 9, 12]]

(It's also significantly slower.)
Well, hmmmmm. OK. Maybe I do understand it. It just wasn't apparent
at first.

Am I close, or did I guess wrong?


You got it.

Note, however, that the same thing is far easier with zip():
zip(*arr) [(1, 4, 7, 10), (2, 5, 8, 11), (3, 6, 9, 12)]

If you need the items to be lists,
[list(i) for i in zip(*arr)] [[1, 4, 7, 10], [2, 5, 8, 11], [3, 6, 9, 12]]

or,
map(list, zip(*arr))

[[1, 4, 7, 10], [2, 5, 8, 11], [3, 6, 9, 12]]

--
Francis Avila

Jul 18 '05 #2

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Chris P. | last post by:
Hi. I've made a program that logs onto a telnet server, enters a command, and then creates a list of useful information out of the information that is dumped to the screen as a result of the...
24
by: Mahesh Padmanabhan | last post by:
Hi, When list comprehension was added to the language, I had a lot of trouble understanding it but now that I am familiar with it, I am not sure how I programmed in Python without it. Now I...
15
by: Darren Dale | last post by:
Hi, I need to replace the following loop with a list comprehension: res= for i in arange(10000): res=res+i In practice, res is a complex 2D numarray. For this reason, the regular output...
18
by: a | last post by:
can someone tell me how to use them thanks
4
by: Gregory Guthrie | last post by:
Sorry for a simple question- but I don't understand how to parse this use of a list comprehension. The "or" clauses are odd to me. It also seems like it is being overly clever (?) in using a...
19
by: bvdp | last post by:
Please help my poor brain :) Every time I try to do a list comprehension I find I just don't comprehend ... Anyway, I have the following bit of code: seq = tmp = for a in range(len(seq)):...
11
by: beginner | last post by:
Hi, Does anyone know how to put an assertion in list comprehension? I have the following list comprehension, but I want to use an assertion to check the contents of rec_stdl. I ended up using...
4
by: beginner | last post by:
Hi All, If I have a list comprehension: ab= c = "ABC" print c
7
by: idiolect | last post by:
Hi all - Sorry to plague you with another newbie question from a lurker. Hopefully, this will be simple. I have a list full of RGB pixel values read from an image. I want to test each RGB band...
6
by: mh | last post by:
I googled and wiki'ed, but couldn't find a concise clear answer as to how python "list comprehensions" got their name. Who picked the name? What was the direct inspiration, another language? ...
2
by: DJRhino | last post by:
Was curious if anyone else was having this same issue or not.... I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
by: Aliciasmith | last post by:
In an age dominated by smartphones, having a mobile app for your business is no longer an option; it's a necessity. Whether you're a startup or an established enterprise, finding the right mobile app...
2
by: giovanniandrean | last post by:
The energy model is structured as follows and uses excel sheets to give input data: 1-Utility.py contains all the functions needed to calculate the variables and other minor things (mentions...
4
NeoPa
by: NeoPa | last post by:
Hello everyone. I find myself stuck trying to find the VBA way to get Access to create a PDF of the currently-selected (and open) object (Form or Report). I know it can be done by selecting :...
1
by: Teri B | last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course. 0ne-to-many. One course many roles. Then I created a report based on the Course form and...
3
by: nia12 | last post by:
Hi there, I am very new to Access so apologies if any of this is obvious/not clear. I am creating a data collection tool for health care employees to complete. It consists of a number of...
0
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...
2
by: GKJR | last post by:
Does anyone have a recommendation to build a standalone application to replace an Access database? I have my bookkeeping software I developed in Access that I would like to make available to other...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.