I was using the operator is
in python to compare identical values, but doing an exercise turns out that it doesn't respond as expected.
Example 1
a = 1
b = 1
print(a is b)
True
Example 2
a = 1000
b = 1000
print(a is b)
False
I don't understand why the examples respond differently if in both cases the values are the same.
There are many very interesting things to comment on this question. Let's go by parts:
Never use
is
to compare valuesThe operator
is
has a very specific purpose and that is to see if two variables "point" to the same object. To understand this, it helps to know a little about the Python data model.If you know C, I would tell you that everything in Python is pointers to objects . If you don't know C, suffice it to say that each Python variable is not a "box" in which you put a value, but rather a "pointer" that points to an object, which actually has the value (and a type) . That is why the variable itself has no type, but the data to which it "points".
This is also true for integers. So when you do:
The python interpreter creates an object of type
int
, stores in that object the value1000
, and makes the identifiera
"point" to that object. It would be the following situation:If you then do
Then a new identifier is created
b
that will point to the same data asa
, since that is what happens when you assign one variable to another (this also applies to lists, strings, or any other type, and even if itb
is the argument of a function to the one you passa
as a parameter). The situation will now be:At this time
a
andb
refer to the same object. Therefore ita is b
will beTrue
because this is what the operator isis
for, to see if both refer to the same object. The operator==
instead compares the objects . Naturallya == b
it will also beTrue
ifa
andb
refer to the same object.A subsection: immutability and reassignment
You may be wondering "This cannot be so, because if I now change the value of
b
doing, for example , the value ofb = b + 1
will also changea
, right?"It turns out not, because an integer is immutable , which means you can't change it to another. The number 1000 is the number 1000, and it can never become the number
1001
.One moment! you will be thinking How not? So what happens if I do...
What happens is quite surprising. The Python interpreter will have to evaluate the right side of the assignment, for which it will create another integer with value 1, and add it to the integer "pointed" by
b
, which as we saw is 1000. The result of that sum is 1001, and therefore Python will create a new data for the result, with value 1001, and reassign the variableb
to point to this new data. The original 1000 has not been modified (it could not, since it is immutable). The thing is therefore like this after the previous line:Naturally now it is false that
a == b
and also thata is b
they point to different objects.So back to your question
This explains the second case in your question:
since these assignments give rise to the following figure:
Where we can clearly see that they point to separate objects, and so
a is b
it's false, but those objects have the same value and soa == b
it's true.Now what is going on here?
Shouldn't this case be the same as before?
Well , it turns out not . Almost inexplicably, the previous lines give rise to the following figure:
Looking at the figure it is clear that it
a is b
is true, but why does 1 behave differently from 1000?This is an optimization detail of the CPython interpreter. It turns out that this interpreter, to improve its performance, has integers between -5 and 256, both inclusive [ reference ], already created in advance , because these integers are used very often. When a variable in your program is assigned to one of these integers, it is made to point to the pre-created data. That's why at the end and they point to "the same 1". And actually all the variables in your program that are equal to 1 will point to "the same 1".
a
b
However, this is a feature that you should not rely on when writing programs. The fact that for those integers in particular (and also for some strings) the
is
works is an "accident". Never rely on this.The operator
is
does not compare that two values are identical, but rather compares where each of them point to.If you use the
id(a)
e functionid(b)
you will see the object they point to.