list assignment using concatenation "*"

Steve R. Hastings steve at hastings.org
Fri Feb 24 21:24:56 EST 2006


> if I do:
> 
> a = [ [0] * 3 ] * 3
> a[0][1] = 1
> 
> I get
> 
> a = [[0,1,0],[0,1,0],[0,1,0]]

The language reference calls '*' the "repetition" operator.  It's not
making copies of what it repeats, it is repeating it.

Consider the following code:

>>> a = []
>>> b = []
>>> a == b
True
>>> a is b
False
>>>
>>> a = b = []
>>> a is b
True
>>> a.append(1)
>>> a
[1]
>>> b
[1]


Each time you use [], you are creating a new list.  So the first code sets
a and b to two different new lists.

The second one, "a = b = []", only creates a single list, and binds both a
and b to that same list.

In your example, first you create a list containing [0, 0, 0]; then you
repeat the same list three times.

>>> a = [[0]*3]*3
>>> a
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> a[0] is a[1]
True
>>> a[0] is a[2]
True

When you run [0]*3 you are repeating 0 three times.  But 0 is not mutable.
When you modify a[0] to some new value, you are replacing a reference to
the immutable 0 with some new reference.  Thus, [0]*3 is a safe way to
create a list of three 0 values.

When you have a list that contains three references to the same mutable,
and you change the mutable, you get the results you discovered.
-- 
Steve R. Hastings    "Vita est"
steve at hastings.org    http://www.blarg.net/~steveha




More information about the Python-list mailing list