Python variable weirdness?
What's going on with my Python variable? old_pos
seems to be linked to pos
:
Code:
pos = [7, 7]
direction =开发者_Go百科 [1, 1]
old_pos = pos
print 'pos = '+str(pos)
print 'old_pos = '+str(old_pos)
pos[0] += direction[0]
pos[1] += direction[1]
print 'pos = '+str(pos)
print 'old_pos = '+str(old_pos)
Output:
pos = [7, 7]
old_pos = [7, 7]
pos = [8, 8]
old_pos = [8, 8]
However, if I replace old_pos = pos
with old_pos = tuple(pos)
or even old_pos = list(pos)
, I don't get this problem:
pos = [7, 7]
old_pos = [7, 7]
pos = [8, 8]
old_pos = [7, 7]
When you say old_pos = pos
, you are not creating a copy of pos
, but just making another reference to the same list. If you want two lists that behave independently, you'll need to make a copy, like using the list(pos)
function as you mention, or using the slice notation pos[:]
.
old_pos = pos
does not create a copy of the object refered to by the name pos
, rather it creates a second reference called old_pos
to the very same object. Actions done to pos
affect the same object referred to by old_pos
. In the same way, the names "Steven" and "Mr. Rumbalski" both refer to me. If you punch Steven in the face, Mr. Rumbalski will be injured, because the two names refer to the same object -- me.
Here are 3 ways to make an actual copy instead of a second reference:
Using slice notation
old_pos = pos[:]
Using the list constructor
old_pos = list(pos)
Using the copy module
from copy import copy
old_pos = copy(pos)
Note that these copies are all shallow copies, which in this case is fine. To learn about the difference between shallow copy and deep copy read the documentation of the copy module.
old_pos
seems to be linked topos
Correct - this:
old_pos = pos
makes old_pos
and pos
point to the same list. It doesn't create a new copy of pos
.
recursive is right about the cause. You can see that they have identical memory addresses:
>>> pos = [7, 7]
>>> old_pos = pos
>>> id(pos)
4299304472
>>> id(old_pos)
4299304472
This is called passing by reference, versus passing by value. You can also remedy this situation by using the copy
module.
>>> from copy import copy
>>> pos = [7, 7]
>>> old_pos = pos
>>> id(pos)
4299304472
>>> id(old_pos)
4299304472
>>> old_pos = copy(pos)
>>> id(old_pos)
4299349240
In addition to the aforementioned comments, some additional steps must be taken in case of multi dimensional arrays. For instance, when you have a two dimensional array a = [[0,1,2],[3,4],[5,6,7,8]]
, the code b = a
will not create an independent copy. However, it will create another reference to the references of the same one dimensional lists within the two dimensional list. To solve this, you must use one of the aforementioned methods for every list within the two dimensional list. For example, b = [i[:] for i in a]
will create an independent copy of the list.
精彩评论