another dictionary q

Ben Caradoc-Davies ben at wintersun.org
Sun Nov 2 01:42:11 CET 2003


On Sun, 02 Nov 2003 01:16:36 +0100, Benoit Dejean <bnet at ifrance.com> wrote:
> Le Sat, 01 Nov 2003 23:03:24 -0800, ruari mactaggart a écrit :
>>>>>verb={}
>>>>>verb[infinitive]=[['','','','','',''],['','','','','',''],['','','','',''
>> ,''],['','','','','',''],['','','','','',''],['','','','','','']]
> 
> verb[infinitive]=[['']*6]*6

These are *not* the same thing. The use of "*" on mutable sequences is a nasty
trap for the unwary, and highlights the difference between copy and reference
semantics in Python. The "*" operator does not copy.

In the first example, the inner lists are distinct, whereas in the second
example, the same inner list is present multiple times in the outer list. I'll
use length two for brevity:

>>> a=[['',''],['','']]
>>> b=[['']*2]*2
>>> a
[['', ''], ['', '']]
>>> b
[['', ''], ['', '']]

They *look* the same, but ...

>>> a[0][0]=1
>>> a
[[1, ''], ['', '']]
>>> b[0][0]=1
>>> b
[[1, ''], [1, '']]

While b *looks* the same as a, it contains one list multiple times, so if you
update one list, it affects all the others.

List comprehensions of list comprehensions are a convenient and succinct way of
creating lists of distinct lists:

>>> c=[['' for j in range(2)] for i in range(2)]
>>> c
[['', ''], ['', '']]
>>> c[0][0]=1
>>> c
[[1, ''], ['', '']]

The indices (i and j) in the list comprehensions are not used in this case:
they are chosen to indicate the meaning of the expression. The innermost
elements of c are accessed by c[i][j] (the dimensions in the ranges are in
reverse order). 

-- 
Ben Caradoc-Davies <ben at wintersun.org>
http://wintersun.org/
Imprisonment on arrival is the authentic Australian immigration experience.




More information about the Python-list mailing list