[Tutor] Issues with initializing lists

Roeland Rengelink r.b.rigilink@chello.nl
Fri, 10 Aug 2001 17:01:55 +0200


Hi Brad,

This one bites everyone sooner or later. To show what's going on, let me
give a simpler example first:

>>> l1 = [1, 2, 3]      # create a list and let l1 refer to that list
>>> l2 = l1             # let l2 refer to the object l1 is referring to     
>>> l1[1] = 'Oops'      # let item 1 in the object l1 is referring to, refer to 'Oops'
>>> l2                  # show the object l2 is referring to
[1, 'Oops', 3]
>>> l1 is l2            # are l1 and l2 referring to the same object ?
1                       # yes

Leona Euler (aka Brad) wrote:
> 
> Hi,
> I am a bit confused about the usage of lists in Python. For an application I
> am writing, I would like to create a list of lists with some default values,
> and then fill in certain items in the list later.
> 
> As an example:
> >>> l1=[[None]*3]*4

Here a list is created with four references to a list containing 3 None
objects
I.e. equivalent to:

>>> l0 = [None, None, None]
>>> l1 = [l0, l0, l0, l0]


> >>> l1
> [[None, None, None], [None, None, None], [None, None, None], [None, None,
> None]]
> 
> Now, suppose I want to fill in the second item in the second sublist. I try
> >>> l1[1][1]='hello'
> 
> Then 'l1' looks like
> 
> >>> l1
> [[None, 'hello', None], [None, 'hello', None], [None, 'hello', None], [None,
> 'hello', None]]
> 
> Note how 'hello' has propagated to each sublist.
> 
> Why is this?
> 

Because the second sublist refers to the same list object as the first,
third and fourth
sublist.

> I could do
> 
> l1=[]
> >>> for i in range(4):
> ...     l1.append([])
> ...     for j in range(3):
> ...             l1[i].append(None)
> ...
> l1[1][1]='hello'
> >>> l1
> [[None, None, None], [None, 'hello', None], [None, None, None], [None, None,
> None]]
> 
> This looks fine. But this approach really seems excessive.
> 

Nevertheless, this is the right approach. You could simplify this
somewhat with:

>>> l = []
>>> for i in range(4):
...     l.append([None]*3)


Hope this helps,

Roeland
-- 
r.b.rigilink@chello.nl

"Half of what I say is nonsense. Unfortunately I don't know which half"