Multi-dimensional list initialization

Andrew Robinson andrew3 at r3dsolutions.com
Tue Nov 6 09:21:07 CET 2012


On 11/05/2012 10:07 PM, Chris Angelico wrote:
> On Tue, Nov 6, 2012 at 4:51 PM, Andrew Robinson
> <andrew3 at r3dsolutions.com>  wrote:
>> I really don't think doing a shallow copy of lists would break anyone's
>> program.
> Well, it's a change, a semantic change. It's almost certainly going to
> break _something_. But for the sake of argument, we can suppose that
> the change could be made. Would it be the right thing to do?
>
> Shallow copying by default would result in extremely weird behaviour.
> All the same confusion would result, only instead of comparing
> [None]*4 with [[None]]*4, there'd be confusion over the difference
> between [[None]]*4 and [[[None]]]*4.
>
> I don't think it would help anything, and it'd result in a lot more
> work for no benefit.
>
> ChrisA
I don't follow.
a=[ None ]*4 would give a=[ None, None, None, None ] as usual.
All four None's would be the same object, but there are automatically 4 
different pointers to it.
Hence,
a[0]=1 would give a=[ 1, None, None, None ] as usual.

a=[ [None] ]*4 would give a=[ [None], [None], [None], [None] ] as usual
BUT:
a[0][0] = 1 would no longer give a=[ [1],[1],[1],[1] ] *Rather* it would 
give
a=[ [1].[None].[None],[None] ]

The None objects are all still the same one, BUT the lists themselves 
are different.

Again, a=[ ["alpha","beta"] * 4 ] would give:
a=[ ["alpha","beta"], ["alpha","beta"], ["alpha","beta"], ["alpha","beta"] ]

All four strings, "alpha", are the same object -- but there are 5 
different lists;  The pointers inside the initial list are copied four 
times -- not the string objects;
But the *lists* themselves are created new for each replication.

If you nest it another time;
[[[None]]]*4, the same would happen; all lists would be independent -- 
but the objects which aren't lists would be refrenced-- not copied.

a=[[["alpha","beta"]]]*4 would yield:
a=[[['alpha', 'beta']], [['alpha', 'beta']], [['alpha', 'beta']], 
[['alpha', 'beta']]]
and a[0][0]=1 would give [[1],[['alpha', 'beta']], [['alpha', 'beta']], 
[['alpha', 'beta']]]]
rather than a=[[1], [1], [1], [1]]

Or at another level down: a[0][0][0]=1 would give: a=[[[1, 'beta']], 
[['alpha', 'beta']], [['alpha', 'beta']], [['alpha', 'beta']] ]
rather than a=[[[1, 'beta']], [[1, 'beta']], [[1, 'beta']], [[1, 'beta']]]

The point is, there would be no difference at all noticed in what data 
is found where in the array;
the *only* thing that would change is that replacing an item by 
assignment would only affect the *location* assigned to -- all other 
locations would not be affected.

That really is what people *generally* want.
If the entire list is meant to be read only -- the change would affect 
*nothing* at all.

See if you can find *any* python program where people desired the 
multiplication to have the die effect that changing an object in one of 
the sub lists -- changes all the objects in the other sub lists.

I'm sure you're not going to find it -- and even if you do, it's going 
to be 1 program in 1000's.



More information about the Python-list mailing list