[Tutor] Question on List Comprehensions

Steven D'Aprano steve at pearwood.info
Tue Nov 22 01:10:14 CET 2011


Charles Karl Becker wrote:
> I'm trying to use a list comprehension to build a list with a variable
> number of lists nested within it (ideally eventually going several
> levels of nesting).  However I seem to be observing some strange
> behavior and was wondering if anyone could take a look at this and
> tell me if what I'm trying to do with list comps is possible, or is a
> map() or for loop the best thing here?


When in doubt, always use a for loop. List comps can't do anything that 
for loops can do, in fact they can do LESS.


> I'm not worrying about incrementing the variables in the later
> examples since I'm confused about their behavior (just simply adding
> new elements to the list rather than nesting the lists; and then
> setting the list to [none] in the last uncommented.  The last
> commented one produces a syntax error, is it impossible to be
> recursive with list comps like that or is my syntax just faulty?)

Your syntax is faulty. List comps are not full-blown replacements for 
for-loops, they are intentionally simple and straightforward.

> board_size = 5
> master_list = []
> 
> # this block produces the desired behavior
> for c in range(board_size):
>     cell = ['', c+1]
>     master_list.append(cell)
> 
> print(master_list)
> 
> # I don't understand why this block behaves the way it does
> master_list = []
> master_list = [board_size * cell]
> print(master_list)

You start of with master_list set to an empty list.

Then you immediately throw away that empty list, and set master_list to 
a list containing a single value, board_size * cell. Since by accident 
cell happens to equal a list left over from the previous part of code, 
you multiply a number 5 by a list ['', 5].

Multiplication of lists performs repetition:

py> ['a', 'b', 'c']*3
['a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c']

By the way, there is no list comprehension there. All you have is a list 
containing a single item.

[42] is not a list comp, it is a list containing a single item, 42.

[4*x] is not a list comp, it is a list containing a single item, 4*x 
(whatever x happens to be).

[4*x for x in (25, 36, 19, 5)] is a list comp.



> # I also don't understand why this block behaves the way that it does
> master_list = []
> master_list = [master_list.append(cell)]
> print(master_list)

You call master_list.append, which modifies master_list in place and 
returns None. So you append cell to master_list, then you create a new 
list [None], and set master_list to that new list, throwing away the 
work you did earlier.

Again, there is no list comprehension here either.


> # this block produces a syntax error, and I'm not sure why
> '''
> master_list = []
> master_list = [x for c in range(board_size) master_list.append(cell)]
> print(master_list)
> '''

Because you don't have a list comprehension. You can't put add arbitrary 
code inside a square brackets [ ]. You have to follow the syntax for a 
list comprehension:

listcomp = [expression for name in sequence]

not

listcomp = [expression for name in sequence another_command]



-- 
Steven



More information about the Tutor mailing list