# Multi-dimensional list initialization

Oscar Benjamin oscar.j.benjamin at gmail.com
Tue Nov 6 15:35:13 CET 2012

On Nov 6, 2012 6:00 AM, "Andrew Robinson" <andrew3 at r3dsolutions.com> wrote:
>
> On 11/05/2012 06:30 PM, Oscar Benjamin wrote:
>>
>>     stuff = [[obj] * n] * m
>>
>> I thought that the multiplication of the inner list ([obj] * n) by m
>> could create a new list of lists using copies. On closer inspection I
>> see that the list being multiplied is in fact [[obj] * n] and that
>> this list can only know that it is a list of lists by inspecting its
>> element(s) which makes things more complicated.
>>
>> I retract my claim that this change would be easy to implement.
>
> In general, people don't use element multiplication (that I have *ever*
seen) to make lists where all elements of the outer most list point to the
same sub-*list* by reference.  The most common use of the multiplication is
to fill an array with a constant, or short list of constants;  Hence,
almost everyone has  to work around the issue as the initial poster did by
using a much longer construction.

That's what I have seen as well. I've never seen an example where someone
wanted this behaviour.

>
> The most compact notation in programming really ought to reflect the most
*commonly* desired operation.  Otherwise, we're really just making people
do extra typing for no reason.

It's not so much the typing as the fact that this a common gotcha.
Apparently many people expect different behaviour here. I seem to remember
finding this surprising at first.

>
> Further, list comprehensions take quite a bit longer to run than low
level copies; by a factor of roughly 10. SO, it really would be worth
implementing the underlying logic -- even if it wasn't super easy.
>
> I really don't think doing a shallow copy of lists would break anyone's
program.
> The non-list elements, whatever they are, can be left as reference copies
-- but any element which is a list ought to be shallow copied.  The
behavior observed in the opening post where modifying one element of a
sub-list, modifies all elements of all sub-lists is never desired as far as
I have ever witnessed.

It is a semantic change that would, I imagine, break many things in subtle
ways.

>
> The underlying implementation of Python can check an object type
trivially, and the only routine needed is a shallow list copy.  So, no it
really isn't a complicated operation to do shallow copies of lists.

Yes but if you're inspecting the object to find out whether to copy it what
do you test for? If you check for a list type what about subclasses? What
if someone else has a custom list type that is not a subclass? Should there
be a dunder method for this?

I don't think it's such a simple problem.

Oscar
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20121106/24158d02/attachment.html>