[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