Multi-dimensional list initialization

Ian Kelly ian.g.kelly at gmail.com
Tue Nov 6 10:19:12 CET 2012


On Tue, Nov 6, 2012 at 1:21 AM, Andrew Robinson
<andrew3 at r3dsolutions.com> wrote:
> 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']]]

You wrote "shallow copy".  When the outer-level list is multiplied,
the mid-level lists would be copied.  Because the copies are shallow,
although the mid-level lists are copied, their contents are not.  Thus
the inner-level lists would still be all referencing the same list.
To demonstrate:

>>> from copy import copy
>>> class ShallowCopyList(list):
...     def __mul__(self, number):
...         new_list = ShallowCopyList()
...         for _ in range(number):
...             new_list.extend(map(copy, self))
...         return new_list
...
>>> a = ShallowCopyList([[["alpha", "beta"]]])
>>> a
[[['alpha', 'beta']]]
>>> b = a * 4
>>> b
[[['alpha', 'beta']], [['alpha', 'beta']], [['alpha', 'beta']],
[['alpha', 'beta']]]
>>> b[0][0][0] = 1
>>> b
[[[1, 'beta']], [[1, 'beta']], [[1, 'beta']], [[1, 'beta']]]
>>> b[0][0] = 1
>>> b
[[1], [[1, 'beta']], [[1, 'beta']], [[1, 'beta']]]

This shows that assignments at the middle level are independent with a
shallow copy on multiplication, but assignments at the inner level are
not.  In order to achieve the behavior you describe, a deep copy would
be needed.

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

The time and memory cost of the multiplication operation would become
quadratic instead of linear.

> 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.

Per the last thread where we discussed extremely rare scenarios,
shouldn't you be rounding "1 in 1000s" up to 20%? ;-)


More information about the Python-list mailing list