0

Asked such a question. Why only the type only str and boolean with the same variables refer to one memory location:

a = 'something'
b = 'something'
if a is b: print('True') # True

but we did not write anywhere a = b. hence the interpreter saw that the strings are equal to each other and made a reference to one memory cell.

Of course, if we assign a new value to either of these two variables, there will be no conflict, so now the variable will refer to another memory location

b = 'something more'
if a is b: print('True') # False

with type boolean going on all the same

a = True
b = True
if a is b: print('True') # True

I first thought that this happens with all mutable types. But no. There remained one unchangeable type - tuple. But it has a different behavior, that is, when we assign the same values ​​to variables, we already refer to different memory cells. Why does this happen only with tuple of immutable types

a = (1,9,8)
b = (1,9,8)
if a is b: print('True') # False
helsereet
  • 111
  • 1
  • 5
  • Related: https://stackoverflow.com/q/17679861/1531971 and https://stackoverflow.com/q/132988/1531971 (Short non-answer: Python can intern Strings.) –  Dec 05 '17 at 18:32
  • 1
    Tuples are immutable, but **their values may change**. You do not have to care about these things. Do not check for equality using `is` in the first place and everything will be fine. – Elis Byberi Dec 05 '17 at 18:37

2 Answers2

0

In Python, == checks for value equality, while is checks if basically its the same object like so:
id(object) == id(object)
Python has some builtin singletons which it starts off with (I'm guessing lower integers and some commonly used strings)
So, if you dig deeper into your statement

a = 'something'
b = 'something'
id(a)
# 139702804094704
id(b)
# 139702804094704
a is b
# True

But if you change it a bit:

a = 'something else'
b = 'something else'
id(a)
# 139702804150640
id(b)
# 139702804159152
a is b
# False

We're getting False because Python uses different memory location for a and b this time, unlike before.
My guess is with tuples (and someone correct me if I'm mistaken) Python allocates different memory every time you create one.

Evya
  • 2,325
  • 3
  • 11
  • 22
  • You are correct! Tuples are immutable, but **their values may change**. That is why they [identical tuples] do not use same memory. – Elis Byberi Dec 05 '17 at 19:06
  • And when you change a value in a tuple, Python allocates a new memory space for the changed one – Evya Dec 05 '17 at 19:08
0

Why do some types cache values? Because you shouldn't be able to notice the difference!

is is a very specialized operator. Nearly always you should use == instead, which will do exactly what you want.

The cases where you want to use is instead of == basically are when you're dealing with objects that have overloaded the behavior of == to not mean what you want it to mean, or where you're worried that you might be dealing with such objects.

If you're not sure whether you're dealing with such objects or not, you're probably not, which means that == is always right and you don't have to ever use is.

It can be a matter of "style points" to use is with known singleton objects, like None, but there's nothing wrong with using == there (again, in the absence of a pathological implementation of ==).

If you're dealing with potentially untrustworthy objects, then you should never do anything that may invoke a method that they control.... and that's a good place to use is. But almost nobody is doing that, and those who do should be aware of the zillion other ways a malicious object could cause problems.

If an object implements == incorrectly then you can get all kinds of weird problems. In the course of debugging those problems, of course you can and should use is! But that shouldn't be your normal way of comparing objects in code you write.

The one other case where you might want to use is rather than == is as a performance optimization, if the object you're dealing with implements == in a particularly expensive way. This is not going to be the case very often at all, and most of the time there are better ways to reduce the number of times you have to compare two objects (e.g. by comparing hash codes instead) which will ultimately have a much better effect on performance without bringing correctness into question.

If you use == wherever you semantically want an equality comparison, then you will never even notice when some types sneakily reuse instances on you.

Daniel Pryden
  • 59,486
  • 16
  • 97
  • 135