Reputation: 647
According to this, python copies references when slicing. I've tried the following:
>>> a=[1,2,3]
>>> b=a[:]
>>> b[1]=0
>>> a
[1, 2, 3]
>>> b
[1, 0, 3]
>>> map(id,a)
[14508376, 14508352, 14508328]
>>> map(id,b)
[14508376, 14508400, 14508328]
Why does b[1]=0
does not change a[1]
(which should be the case if b[1]
was indeed a reference to the same object, one might think)? Instead, it seems to generate a new reference/id and change the new object. Anywhere I can read up on this behavior in more detail?
Upvotes: 1
Views: 49
Reputation: 530990
Suppose you start with a = [1,2,3]
. In Python's data model, this means that a
refers to an object in memory:
a -> [ * | * | * ]
| | |
v v v
1 2 3
With b = a
, you simply point another name at the same object:
a -> [ * | * | * ] <- b
| | |
v v v
1 2 3
b[1] = 0
changes the same reference a[1] = 0
would:
0
^
|
a -> [ * | * | * ] <- b
| |
v v
1 2 3
(The 2
is still in memory, possibly referenced directly or indirectly via some other name, but not via a
or b
anymore.)
With b = a[:]
, you create a new list, but that new list contains references to the same object:
a -> [ * | * | * ]
| | |
v v v
1 2 3
^ ^ ^
| | |
b -> [ * | * | * ]
Now when you write b[1] = 0
, you aren't changing a[1]
, because a
and b
are distinct list objects.
a -> [ * | * | * ]
| | |
v v v
1 2 3
^ ^
| |
b -> [ * | * | * ]
|
v
0
Ned Batchelder's blog post (and subsequent PyCon talk) is an excellent overview of Python's name model.
Upvotes: 5