Yes, you're basically correct. In Python, a variable name can be thought of as a reference to a value (not in terms of a C++ reference, though that works similarly, more just stating that it refers to something).
As an aside, the Python way is very similar to the C++ int &b = a
, which just means a
and b
refer to the same value.
Or the C int *pb = &a
, which means a
and *pb
refer to the same value, but with all the confusion that brings to people who haven't yet accepted the brain-bendedness of C :-)
Assigning to the variable name in Python makes the name refer to a different value, it never copies the value itself:
a = 7 # Create "7", make "a" refer to it.
b = a # make "b" refer to the "7" as well.
a = 42 # Create "42", make "a" refer to it, b still refers to the "7".
(I say "create" but that's not necessarily so - if a value already exists somewhere, it may re-use it).
In a C-like language, that second statement b = a
creates a new value, copies the "7" into it and then names that b
. In Python, it simply ends up with a
and b
referring to the same value.
Where the underlying data is immutable (cannot be changed), that usually makes Python look as if it's behaving identically to the way C does it.
But, for mutable data (same as using pointers in C or references in C++), people can sometimes be surprised because they don't realise that the value behind it may be shared:
>>> a = [1,2,3] ; print a
[1, 2, 3]
>>> b = a ; print b
[1, 2, 3]
>>> a[1] = 42 ; print a
[1, 42, 3]
>>> print b #WTH?
[1, 42, 3]
There are ways to get independent copies of a value, with things such as:
b = a[:]
b = [item for item in a]
(which will work to one level, where b = a
works to zero levels), or using deepcopy
if you want if totally unique, to whatever level is necessary.