[Tutor] filling 2d array with zeros
Steven D'Aprano
steve at pearwood.info
Tue Sep 28 02:46:20 CEST 2010
On Tue, 28 Sep 2010 06:00:41 am Alex Hall wrote:
> > [ [0]*3 ]*4 behaves the same way. There's no problem in the inner
> > list, but the outer list doesn't make four copies of [0,0,0], it
> > has *one* list repeated four times. Modify one, modify them all.
>
> That makes sense. Basically, the * operator in this case acts as a
> copying command. For simple data types this is fine, but throw in a
> complex type, in this case a list (though I expect that any object
> would do this) and you are just doing what Python does to copy
> objects: copying the memory location, not making a deep copy and
> getting a duplicate object. I never would have thought of that.
> Thanks again for the great explanation!
No, be careful about your terminology. I get that you understand what is
going on, but you're saying it wrong. The * operator doesn't make
copies. I know it's tempting to say it does, sometimes I catch myself
saying so myself, but what Python is doing is making multiple
references to the same object. The object is not copied.
It may be easier if you think about the underlying C implementation
(under the hood, in the engine) rather than the Python level. At the
Python level, objects can be in multiple places at once. Objects like
lists can even be inside themselves:
>>> L = []
>>> L.append(L)
If you've watched Doctor Who as a child, and seen his TARDIS (which of
course is bigger on the inside than the outside) land inside itself,
such strange loops won't hold any fear for you at all :)
But at the C level, Python doesn't make copies of any object unless
necessary. The *name* L is a pointer to the list object. When you
execute:
L = []
Python creates a name L which then points ("refers to") to a list
object. When you next do this:
L.append(L)
Python doesn't move the list object into itself -- that would be a good
trick. Besides, objects are big, complex chunks of memory and moving
them around would be slow, so Python leaves the list where it is and
simply places a pointer to L into the appropriate list position.
(But don't forget that Python is not necessarily written in C. There's
Jython, written in Java, and CLPython written in Lisp, and many others.
How they implement objects may be different. What happens under the
hood isn't important, so long as the behaviour at the Python level
remains the same.)
So at the Python level, there is never any copying of objects unless you
specifically ask for it, and the * operator doesn't make any copies at
all. It repeats the one object multiple times.
--
Steven D'Aprano
More information about the Tutor
mailing list