130

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
Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
pic11
  • 14,267
  • 21
  • 83
  • 119

6 Answers6

188

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).

Stefan
  • 919
  • 2
  • 13
  • 24
Jochen Ritzel
  • 104,512
  • 31
  • 200
  • 194
  • 9
    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 Dec 13 '15 at 03:01
  • 16
    @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](http://www.laurentluce.com/posts/python-integer-objects-implementation/) – ted Jan 28 '16 at 13:57
  • @Bill @ted For immutable objects, such as integers, floats, strings or tuples, `is` is equivalent to `==`. When the object is immutable, there are no more possible _versions_ of the object, nor is it possible to modify it, so asking whether the object _is_ the same is irrelevant, and there is only one such object that all variables reference. – AndresR Apr 08 '17 at 10:00
  • 3
    @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. – Jochen Ritzel Apr 10 '17 at 13:43
  • 2
    @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? – AndresR Apr 10 '17 at 16:16
  • 2
    @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. – Jochen Ritzel Apr 11 '17 at 16:59
22

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
ted
  • 4,791
  • 5
  • 38
  • 84
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)
Bill
  • 10,323
  • 10
  • 62
  • 85
13

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

MarredCheese
  • 17,541
  • 8
  • 92
  • 91
Mark Rushakoff
  • 249,864
  • 45
  • 407
  • 398
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..

user1767754
  • 23,311
  • 18
  • 141
  • 164
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.

  • 1
    Excellent doc catch. – prosti May 04 '19 at 15:41
  • 1
    `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. – ArtOfWarfare Oct 08 '20 at 22:07