user6058437
user6058437

Reputation:

Understanding references in Python

Following example:

a = 1
b = a
b = 3
print(a) # gives 1

But, when I do:

a = [1,2]
b = a
b[0] = 3
print(a) # gives [3,2]

How do I know whether a variable is treated like a (C++ type) reference or a plain variable? Are elementary data types just an exception to the 'everything is a reference' rule? What detail of the underlying mechanics am I missing?

Upvotes: 3

Views: 1246

Answers (4)

Tonechas
Tonechas

Reputation: 13723

For a better grasp of this kind of issues, I would encourage you to use the Online Python Tutor. This is an extremely handy tool that renders a graphical representation of the objects in memory while the code is executed step by step.

To show the Online Python Tutor in action I have splitted a toy example into small snippets and then captured the corresponding screenshots. Hopefully this will help you figure out how Python referencing works.

a = 1
b = a

Step 1

b = 2

Step 2

x = [a, b]
y = x

Step 3

y[1] = 3

Step 4

If you want to play around with this code, follow this link.

Upvotes: 1

Mark Ransom
Mark Ransom

Reputation: 308121

All variables in Python are references. Elementary data types aren't an exception.

In the first example, you reassign b. It no longer references the same object as a.

In the second example, you modify b. Since you've previously set a and b to be references to the same object, the modification applies to a as well.

Upvotes: 3

Bi Rico
Bi Rico

Reputation: 25813

Everything is a reference. All python variables reference objects, all objects can have more than one reference.

The difference you're seeing is between the assignment operator and the __setitem__ operator. The syntax is similar, but they do different things.

This is an assignment, it updates the reference of variable var.

var = 'something'

This uses setitem, it's essentially a method call on the left hand side object.

obj[i] = 'thing'
# is the same as
obj.__setitem__(i, 'thing')

What __setitem__ does depends on the type, but generally it will modify obj. In that sense, b[0] = 3 is more b.append(3) than it is like b = 3. Immutable types do not have a setitem method and throw an error on the setitem operator.

Upvotes: 0

cdarke
cdarke

Reputation: 44344

Every name is a plain reference.

A variable name is a reference to an object, and what matters is the properties of the object. Rule: numbers (int, float, etc.), strings, tuples (and others) are immutable - read-only. Lists, dictionaries, sets (and others) are mutable.

So the difference you observed is because int's are immutable - they cannot be changed. Whereas lists are mutable - they can be changed.

Assigning a = b in both cases copies the reference. It's what happens when you reassign b, in this case a new object is created referenced by the left-hand-side. With a mutable object the object referenced is changed, and it would not matter which reference is used.

Upvotes: 0

Related Questions