For...in questions (Python)

142 Views Asked by At

I was trying some different ways to run some for...in loops. Consider a list of lists:

list_of_lists = []
list = [1, 2, 3, 4, 5]
for i in range(len(list)):
    list_of_lists.append(list) # each entry in l_o_l will now be list

Now let's say I want to have the first "column" of l_o_l be included in a separate list, a. There are several ways I can go about this. For example:

a = [list[0] for list in list_of_lists] # this works (a = [1, 1, 1, 1, 1])

OR

a=[]
for list in list_of_lists:
    a.append(hit[0]) #this also works

For the second example, however, I would imagine the "full" expansion to be equivalent to

a=[]
a.append(list[0] for list in list_of_lists) #but this, obviously, produces a generator error

The working "translation" is, in fact,

a=[]
a.append([list[0] for list in list_of_lists]) #this works

My question is on interpretation and punctuation, then. How come Python "knows" to append/does append the list brackets around the "list[0] for list in list_of_lists" expansion (and thus requires it in any rewrite)?

2

There are 2 best solutions below

0
On

The issue here is that list comprehensions and generator expressions are not just loops, they are more than that.

List comprehensions are designed to be an easy way to build up a list from an iterable, as you have shown.

Your latter two examples both don't work - in both cases you are appending the wrong thing to the list - in the first case, a generator, the second appends a list inside your existing list. Neither of these are what you want.

You are trying to do something in two different ways at the same time, and it doesn't work. Just use the list comprehension - it does what you want to do in the most efficient and readable way.

Your main problem is you seem to have taken list comprehensions and generator expressions and not understood what they are and what they are trying to do. I suggest you try to understand them further before using them.

0
On

My question is on interpretation and punctuation, then. How come Python "knows" to append/does append the list brackets around the "hit[0] for list in list_of_lists" expansion (and thus requires it in any rewrite)?

Not sure what that is supposed to mean. I think you might be unaware that in addition to list comprehensions [i*2 for i in range(0,3)] there are also generator expressions (i*2 for i in range(0,3)).

Generator expressions are a syntax for creating generators that perform a mapping, just like a list comprehension (but as a generator). Any list comprehension [c] can be rewritten list(c). The reason why there is a naked c inside list() is because where generator expressions appear as a parameter to a call, it is permitted to drop the brackets. This is what you are seeing in a.append(hit[0] for list in list_of_lists).