Multi-dimensional list initialization

Hans Mulder hansmu at xs4all.nl
Mon Nov 5 10:13:06 CET 2012


On 5/11/12 07:27:52, Demian Brecht wrote:
> So, here I was thinking "oh, this is a nice, easy way to initialize a 4D matrix"
> (running 2.7.3, non-core libs not allowed):
> 
> m = [[None] * 4] * 4
> 
> The way to get what I was after was:
> 
> m = [[None] * 4, [None] * 4, [None] * 4, [None * 4]] 

Or alternateively:

m = [[None] * 4 for _ in range(4)]

> (Obviously, I could have just hardcoded the initialization, but I'm too
> lazy to type all that out ;))
> 
> The behaviour I encountered seems a little contradictory to me.
> [None] * 4 creates four distinct elements in a single array

Actually, it creates a list with four references to the same object.
But then, this object is immutable, so you won't notice that it's the
same object.

> while [[None] * 4] * 4 creates one distinct array of four distinct
> elements, with three references to it:

We usually phrase that as "a list with four references to the
same list".  The first reference is not special in any way.

>>>> a = [None] * 4
>>>> a[0] = 'a'
>>>> a
> ['a', None, None, None]
> 
>>>> m = [[None] * 4] * 4
>>>> m[0][0] = 'm'
>>>> m
> [['m', None, None, None], ['m', None, None, None], ['m', None, None, None], ['m', None, None, None]]
> 
> Is this expected behaviour

Yes.

> and if so, why? In my mind either result makes sense, but the
> inconsistency is what throws me off.

There's no inconsistency: in both cases you get a list with four
references to the same object.  The only difference is that in the
fist case, the references are to an immutable object, so the fact
that it's the same object won't hurt you.


Hope this helps,

-- HansM



More information about the Python-list mailing list