[Tutor] When is = a copy and when is it an alias

Steven D'Aprano steve at pearwood.info
Mon Jan 27 10:31:51 CET 2014


Hi Denis, and welcome!

On Sun, Jan 26, 2014 at 10:16:25PM -0800, Denis Heidtmann wrote:

> Running python 2.7 in linux
> 
> Below are two extremes.  Can I get some guidance on this?

In Python, = is ALWAYS an alias, never a copy, unless you explicitly do 
something to make a copy. For example, with dicts, there is a `copy` 
method:

newdict = olddict.copy()

But it's not always *obvious* that you're just aliasing the same object. 
For example, this is obvious:

py> a = []
py> b = a  # b is now a new name for a
py> a.append(42)  # modifies the list in place
py> b
[42]

but this is not:

py> a = 23
py> b = a  # b is now a new name for a
py> a = a + 1
py> b
23


In this second case, b is unchanged because `a = a + 1` doesn't *modify* 
a, it makes a new value (23 + 1 => 24) and assigns that new value to a, 
leaving b unchanged.


In your example below, I take it you are using numpy. You should say so, 
in case it is unclear.

> >>> a=zeros((2,3),dtype=int)
> >>> b=a
> >>> a[:,0]=[1,2]
> >>> a
> array([[1, 0, 0],
>        [2, 0, 0]])
> >>> b
> array([[1, 0, 0],
>        [2, 0, 0]])

In this example, you bind the name "a" to an array of zeroes, then bind 
the name "b" to the same array. "Name binding" is another term for 
assignment in Python. So a and b are two names for the same array. When 
you modify the array via the name "a", b sees the same changes because 
they are the same array.

Even though the line

a[:,0] = [1, 2]

looks like an assignment, it's not actually a name binding, because 
you're only assigning to a slice of the array, not the name. That makes 
it an in-place modification, just like appending to a list.

But this code that follows:

> >>> a=2
> >>> a
> 2
> >>> b
> array([[1, 0, 0],
>        [2, 0, 0]])

is different. Here, the line `a = 2` is an actual name binding. It makes 
the name `a` refer to the value 2, instead of the array it used to refer 
to. But that doesn't change the array in any way, nor does it change 
`b`, so b is unaffected.


Hope this helps,


-- 
Steven


More information about the Tutor mailing list