39

When I ran this script (Python v2.6):

a = [1,2]
b = a
a.append(3)
print a
>>>> [1,2,3]
print b
>>>> [1,2,3]

I expected print b to output [1,2]. Why did b get changed when all I did was change a? Is b permanently tied to a? If so, can I make them independent? How?

3
  • 3
    @Felix I'd say not quite a dup - he isn't asking only how to clone but rather why Python behaves a certain way. Commented Jul 22, 2011 at 17:45
  • 4
    "Python has names" is very good part of even better tutorial/introduction regarding this behavior. Commented Jul 22, 2011 at 17:46
  • @thegrinner: Yeah, I was a bit too quick. Just hinting at it would have been better. Commented Jul 22, 2011 at 18:26

6 Answers 6

64

Memory management in Python involves a private heap memory location containing all Python objects and data structures.

Python's runtime only deals in references to objects (which all live in the heap): what goes on Python's stack are always references to values that live elsewhere.

>>> a = [1, 2]

python variables

>>> b = a

python variables

>>> a.append(3)

python variables

Here we can clearly see that the variable b is bound to the same object as a.

You can use the is operator to tests if two objects are physically the same, that means if they have the same address in memory. This can also be tested also using the id() function.

>>> a is b
>>> True
>>> id(a) == id(b)
>>> True

So, in this case, you must explicitly ask for a copy. Once you've done that, there will be no more connection between the two distinct list objects.

>>> b = list(a)
>>> a is b
>>> False

python variables

Sign up to request clarification or add additional context in comments.

Comments

13

Objects in Python are stored by reference—you aren't assigning the value of a to b, but a pointer to the object that a is pointing to.

To emulate assignation by value, you can make a copy like so:

import copy

b = copy.copy(a)

# now the code works as "expected"

Be aware this has performance disadvantages.

In the case of an array, there's a special method that relies on slices:

b = a[:]

# code also works as expected here

Update– In addition to this, with some objects you can use the constructor—this includes lists:

b = list(a)

1 Comment

DiggyF pointed this out in a comment below - you'll want to replace b = a[:] with b = list(a) for both readability reasons and for anything that works with numpy.
4

Short answer - Pointers.

When you type b = a it is setting b to look at the same array that a looks at. You have to make a new array with copies of the elements to separate them. In this case, something like b = [n for n in a] would work fine. For more complex operations you may want to check out http://docs.python.org/library/copy.html.

1 Comment

Also b = a[:] works, and it's more "pythonic" (or so they say)
4

You might want to look at this link. The problem you have here is a and b both point to the same memory location, so changing one changes the other. Instead, you want to do something like this:

a = [1,2]
b = list(a)

1 Comment

From the article in the link: "Next time you see a [:] try to replace it with list, your code should be more readable. Do it, the devil is in the details.". So it is advisable to use b=list(a). This is also a good idea because when people switch from a list to a numpy array, then a[:] will be reference to the same data.
3

a is a pointer to the list [1,2].

When you do the assignment b = a the value of b is the address of the list [1,2].

So when you do a.append(3) you are not actually changing a, you are changing the list that a points to. Since a and b both point to the same list, they both appear to change when you modify the other.

Comments

3

If you simply want to copy the contents of list a to b, instead of making b a pointer to a:

b = a[:]

Using the slice operator will copy the contents of the list into b such that you example would become:

a = [1,2]
b = a[:]
a.append(3)
print a
>>>> [1,2,3]
print b
>>>> [1,2]

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.