Multi-dimensional list initialization

Chris Angelico rosuav at
Tue Nov 6 03:01:46 CET 2012

On Tue, Nov 6, 2012 at 12:32 PM, Oscar Benjamin
<oscar.j.benjamin at> wrote:
> I was just thinking to myself that it would be a hard thing to change
> because the list would need to know how to instantiate copies of all
> the different types of the elements in the list. Then I realised it
> doesn't. It is simply a case of how the list multiplication operator
> is implemented and whether it chooses to use a reference to the same
> list or make a copy of that list. Since all of this is implemented
> within the same list type it is a relatively easy change to make
> (ignoring backward compatibility concerns).
> I don't see this non-copying list multiplication behaviour as
> contradictory but has anyone ever actually found a use for it?

Stupid example of why it can't copy:

bad = [open("test_file")] * 4

How do you clone something that isn't Plain Old Data? Ultimately,
that's where the problem comes from. It's easy enough to clone
something that's all scalars (strings, integers, None, etc) and
non-recursive lists/dicts of scalars, but anything more complicated
than that is rather harder.

If you want a deep copy and are prepared to handle any issues that
might result, you can do this:

>>> import copy
>>> a=[[2,3,4]]
>>> a.extend(copy.deepcopy(a))
>>> a[0][1]=10
>>> a
[[2, 10, 4], [2, 3, 4]]

And some things just won't work:
>>> bad.extend(copy.deepcopy(bad))
Traceback (most recent call last):
  File "<pyshell#17>", line 1, in <module>
  File "C:\Python32\lib\", line 147, in deepcopy
    y = copier(x, memo)
  File "C:\Python32\lib\", line 209, in _deepcopy_list
    y.append(deepcopy(a, memo))
  File "C:\Python32\lib\", line 166, in deepcopy
    rv = reductor(2)
TypeError: cannot serialize '_io.TextIOWrapper' object

The default behaviour is safe and reliable. When you want something
other than the default, there are ways of doing it.


More information about the Python-list mailing list