-1

Python seems to be inconsistent.

x = 100
y = 100
x is y

Returns True, yet:

x = 300
y = 300
x is y

Returns False.

I even tried with new, clean variables:

> x = 100
> y = 100
> x is y
True
> x = 300
> y = 300
> x is y
False
> x = 100
> y = 100
> x is y
True
> x2 = 300
> y2 = 300
> x2 is y2
False
> x2
300
> y2
300
> x2 is y2
False
> x2 = 100
> y2 = 100
> x2 is y2
True

What is happening here? Am I confused about the "is" key word?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Moffen
  • 1,817
  • 1
  • 14
  • 34

1 Answers1

5

The is keyword compares whether two things are actually the same object. An easy way to think about this is in terms of memory addresses – that is, x is y is another way of writing id(x) == id(y)

There is no guarantee that two objects assigned to the same value will share the same memory address. Sometimes they will, though. That's all that's going on.

If you wish to compare the variables' values, use the comparison operator:

x == y

Edit: upon doing some research, it seems that python uses the same memory adresses for integers in the range [-5, 256] (this is pretty arbitrary, but there is some reasoning for it: it's just some common negative numbers along with 0 - 255, plus 256 because it's also a common number). That would explain why is returns True for 100 but not 300.

So, 256 is 256 returns True, but 257 is 257 returns False

Alec
  • 8,529
  • 8
  • 37
  • 63
  • Python only creates one object for small-ish numbers, which is why `is` will always return `True` for them. Above a threshold, a 'new' number will be created each time. – SyntaxVoid Oct 10 '19 at 22:46
  • @SyntaxVoid it's for ints in the range [-5, 256] – Alec Oct 10 '19 at 22:49
  • 2
    Stop talking about memory addresses, it really muddies the issue. `is` compares object identity. The whole point is objects, not memory addresses – juanpa.arrivillaga Oct 10 '19 at 22:50
  • @juanpa.arrivillaga could you please explain a little further? – Moffen Oct 10 '19 at 22:53
  • 2
    @Moffen python is a high-level language. It is almost never useful to discuss things at the level of "memory address". It is better to speak in terms of objects, object identity etc. I'm not saying that this answer is "wrong" or even "bad" or anything like that. The answer is good, I'm just saying, there is no need to explain things in terms of "memory addresses" which is almost never a good level to talk about things in Python. Ever. – juanpa.arrivillaga Oct 10 '19 at 23:02
  • 2
    Also, note, `id` **is not a function that provides a memory address**. It is a function that guarantees a unique integer for the lifetime of an object. The CPython implementation *happens* to use the address of the PyObject header, but that really *is not relevant*. Again, don't think in terms of low-level implementation details, think in terms of objects. Also, consider `class Foo: pass` and `id(Foo()) == id(Foo())`... get any surprising results? – juanpa.arrivillaga Oct 10 '19 at 23:03
  • I had a thorough answer about CPython internals ready before this answer was posted but was slow to submit because I wanted to include [this page from the CPython docs](https://github.com/python/cpython/blob/1d8b04edfdc3030e645730492bfcc27b75718b96/Doc/c-api/long.rst). Damn you, dupe-hammer! :P – jDo Oct 10 '19 at 23:04