Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When, if ever, to use the 'is' keyword in Python?

Tags:

python

keyword

Today I learnt about the is keyword in Python and tried the following:

>>> x=2+2
>>> y=4
>>> x is y
True

I started off trying is with integers because I knew the answer would be False -- so I found the result very surprising! To give some context, my background is C++ and C# where there is a distinction between value types and object types. In Python, as I now realize, everything is a reference type.

It seems the reason that x is y is True is the same as explained in this question, How is the 'is' keyword implemented in Python?, which relates to using is with strings. I.e. the run-time environment saves memory by sharing, or "interning" integers just as it does with strings -- this is explained in more detail in answers to a question: Python “is” operator behaves unexpectedly with integers I found after my initial post.

Another thing I find surprising is that the value that is returns is implementation dependent. Which relates to my main question. In the referenced question about the implementation of is w.r.t strings, there was some discussion about when to use is, with several users saying they would (almost) never use it. So my question is, when should the is keyword be used? What are some canonical examples, or general rules?

like image 225
TooTone Avatar asked Apr 05 '14 19:04

TooTone


People also ask

What is the difference between IS and == in Python?

The == operator compares the value or equality of two objects, whereas the Python is operator checks whether two variables point to the same object in memory.

Is keyword an example?

Keywords are the words and phrases that people type into search engines to find what they're looking for. For example, if you were looking to buy a new jacket, you might type something like “mens leather jacket” into Google. Even though that phrase consists of more than one word, it's still a keyword.

Is Int a keyword in Python?

there are no keywords in python as such, just statements. int is not a statement it is a name that happens (by design) to be bound by default to the int type. All names can be rebound to other objects.

Is type a keyword in Python?

Using type as a keyword argument to a function will mask the built-in function "type" within the scope of the function. So while doing so does not raise a SyntaxError , it is not considered good practice, and I would avoid doing so.


3 Answers

"is tests for identity, not equality. That means Python simply compares the memory address a object resides in"

There is a simple rule of thumb to tell you when to use == or is.

  • == is for value equality. Use it when you would like to know if two objects have the same value.
  • is is for reference equality. Use it when you would like to know if two references refer to the same object.

In general, when you are comparing something to a simple type, you are usually checking for value equality, so you should use ==.

is will return True if two variables point to the same object, == if the objects referred to by the variables are equal.

>>> a = [1, 2, 3]
>>> b = a
>>> b is a 
True
>>> b == a
True
>>> b = a[:]
>>> b is a
False
>>> b == a
True

The second test only works because Python caches small integer objects, which is an implementation detail. For larger integers, this does not work:

>>> 1000 is 10**3
False
>>> 1000 == 10**3
True
The same holds true for string literals:

>>> "a" is "a"
True
>>> "aa" is "a" * 2
True
>>> x = "a"
>>> "aa" is x * 2
False
>>> "aa" is intern(x*2)
True

Note: "Due to automatic garbage-collection, free lists, and the dynamic nature of descriptors, you may notice seemingly unusual behaviour in certain uses of the is operator, like those involving comparisons between instance methods, or constants."

Because of the way the CPython reference implementation works, you'll get unexpected and inconsistent results if you mistakenly use is to compare for reference equality on integers:

>>> a = 500
>>> b = 500
>>> a == b
True
>>> a is b
False

That's pretty much what we expected: a and b have the same value, but are distinct entities. But what about this?

>>> c = 200
>>> d = 200
>>> c == d
True
>>> c is d
True

This is inconsistent with the earlier result. What's going on here? It turns out the reference implementation of Python caches integer objects in the range -5..256 as singleton instances for performance reasons. Here's an example demonstrating this:

>>> for i in range(250, 260): a = i; print "%i: %s" % (i, a is int(str(i)));
... 
250: True
251: True
252: True
253: True
254: True
255: True
256: True
257: False
258: False
259: False

This is another obvious reason not to use is: the behavior is left up to implementations when you're erroneously using it for value equality.

like image 117
heretolearn Avatar answered Nov 09 '22 03:11

heretolearn


You should use is when you want to know whether two objects are the same object. Don't use it when you want to know whether two objects have the same value.

There is a canonical example, but it is unfortunately not very helpful. People will tell you to always test for the None value using x is None instead of x == None. However, there is little practical difference between these cases. (See this question for explanation.)

In some situations, you may wind up creating objects which have the same value but are distinct objects. For instance, you could imagine creating a fantasy wargame in which the player can magically create minions to battle his opponent. So the player might create 100 identical orcs or whatever. Each orc could be represented by an object, and they would be identical in that they have the same properties, but still distinct in that there would be 100 separate objects. Now if the opponent tries to cast a "fireball" spell on one of these orcs, while on the same turn the player tries to cast "protect against fire" on an orc, you might want to check if the target of the fireball spell is the target of the protection spell. Equality wouldn't be enough, because all the orcs are equal, but only one particular orc is the target of each spell, and you want to know if the two targets are the same object. This is a rather contrived example, but should give a broad idea of the kind of situation where you might wind up using is.

like image 38
BrenBarn Avatar answered Nov 09 '22 01:11

BrenBarn


Firstly, is the reason that x is y is True the same as explained in this question, How is the 'is' keyword implemented in Python?, which relates to using is with strings?

It's similar. Integers from -5 to 256 are cached. This is used for performance purposes.

So my question is, when should the is keyword be used?

You can use is to check if two references are to the same object (it checks objects identity). Also, it's recommended to use is when you will compare an object reference with None:

if some_object is None:
    # ...
like image 29
Christian Tapia Avatar answered Nov 09 '22 01:11

Christian Tapia