143

How to check whether two variables reference the same object?

x = ['a', 'b', 'c']
y = x                 # x and y reference the same object
z = ['a', 'b', 'c']   # x and z reference different objects
0

6 Answers 6

199

That’s what is is for.

In the example, x is y returns True because it is the same object while x is z returns False because it are different objects (which happen to hold identical data).

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

7 Comments

In the example, x is z returns False. But if x and z are assigned the same values instead of lists (for example x, z = 13, 13) then x is z returns True. Why is that?
@Bill: That is an artefact of how python handles ints. Python allocates integer objects to which x and z point. Since small integers are failry common (-1 as an error value, 0 any time you actually index something, small numbers are usually reasonable default values) Python optimizes by preallocating small numbers (-5 to 256) and reuses the same integer object. Thus your example only works for numbers in this range. Try assigning something larger, i.e. 270. For more info look here
@AndresR No that is wrong. is checks if two names reference the same memory location. It has nothing to do with the object itself. It's easy to have immuteable objects like strings that are equal but not stored at the same location, for example ''a'*10000 is 'a' * 10000 is False.
@JochenRitzel You are totally right, thank you for this comment! So then, I don't get what is happening with "af" is "af" or () is ()... why do they share the same memory location?
@AndreasR For literal strings/numbers in the code the compiler checks that they exist only once and reuses them. Special values such as (), None, True, False etc are defined to be singletons too. During execution the runtime also tries to reuse small numbers and strings, but in the end it's a tradeoff between speed and memory and what happends depends on how the Python runtime was implemented.
|
27

While the two correct solutions x is z and id(x) == id(z) have already been posted, I want to point out an implementation detail of python. Python stores integers as objects, as an optimization it generates a bunch of small integers at its start (-5 to 256) and points EVERY variable holding an integer with a small value to these preinitialized objects. More Info

This means that for integer objects initialized to the same small numbers (-5 to 256) checking if two objects are the same will return true (ON C-Pyhon, as far as I am aware this is an implementation detail), while for larger numbers this only returns true if one object is initialized form the other.

> i = 13
> j = 13
> i is j
True

> a = 280
> b = 280
> a is b
False

> a = b
> a
280
> a is b
True

Note: the behaviour may differ between an interactive terminal or scripts. See i.e. pythontutor which notes:

For strings and numbers, you can't rely on id() or is behaving identically to CPython on your computer (example); when teaching beginners, never rely on these since they’re implementation-specific and differ between REPL and scripts

This answer touched on ints, for strings have a look at string interning, i.e. this thread is relevant.

4 Comments

python3.6: a = 98765; b = 98765; a is b => True. Something has changed apparently.
@MikhailKalashnikov Nope. I tested on Python 3.6.2, this still exists.
still exists on python 3.7.7
My python version is 3.8.10 and i got "False" when I using python interpreter. But when i write in python script I got "True" even the number is large.
13

You can also use id() to check which unique object each variable name refers to.

In [1]: x1, x2 = 'foo', 'foo'

In [2]: x1 == x2
Out[2]: True

In [3]: id(x1), id(x2)
Out[3]: (4509849040, 4509849040)

In [4]: x2 = 'foobar'[0:3]

In [5]: x2
Out[5]: 'foo'

In [6]: x1 == x2
Out[6]: True

In [7]: x1 is x2
Out[7]: False

In [8]: id(x1), id(x2)
Out[8]: (4509849040, 4526514944)

1 Comment

@ted's note on the use of id is quite relevant here.
13

y is x will be True, y is z will be False.

Comments

4

I really like to have a visual feedback, that's why I sometimes just open up http://www.pythontutor.com/visualize.html#mode=edit to see how the memory is allocated and what is referencing what.

enter image description here

Added this awesome gif as this reply is about visualizing..

Comments

4

This is from docs.python.org: "Every object has an identity, a type and a value. An object’s identity never changes once it has been created; you may think of it as the object’s address in memory. The ‘is’ operator compares the identity of two objects; the id() function returns an integer representing its identity."

Apparently every time you change the value the object is recreated as indicated by the identity changing. The line x=3 followed by the line x=3.14 gives no error & gives different identities, types and values for x.

2 Comments

Excellent doc catch.
x is a name identifying an object with a value of 3, not an object itself. When you did x=3.14, you didn't change the object that was previously identified by x - you changed which object the name x was referring to.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.