Python 'is' operator behavioral difference while running as a script and running on terminal

My Google-fu has failed me.

In Python, are the following two tests for equality equivalent (ha!)?

n = 5 # Test one. if n == 5:     print 'Yay!'  # Test two. if n is 5:     print 'Yay!' 

Does this hold true for objects where you would be comparing instances (a list say)?

Okay, so this kind of answers my question:

L = [] L.append(1) if L == [1]:     print 'Yay!' # Holds true, but...  if L is [1]:     print 'Yay!' # Doesn't. 

So == tests value where is tests to see if they are the same object?


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
>>> b == a
>>> b = a[:]
>>> b is a
>>> b == a

In your case, 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
>>> 1000 == 10**3

The same holds true for string literals:

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

Please see this question as well.

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 ==. For example, the intention of your example is probably to check whether x has a value equal to 2 (==), not whether x is literally referring to the same object as 2.

Something else to note: 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
>>> a is b

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
>>> c is d

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.

Note that this is why if foo is None: is the preferred null comparison for python. All null objects are really pointers to the same value, which python sets aside to mean "None"

if x is True: and if x is False: also work in a similar manner. False and True are two special objects, all true boolean values are True and all false boolean values are False

== determines if the values are equivalent, while "is" determines if they are the exact same object.

They are completely different. is checks for object identity, while == checks for equality (a notion that depends on the two operands' types).

It is only a lucky coincidence that "is" seems to work correctly with small integers (e.g. 5 == 4+1). That is because CPython optimizes the storage of integers in the range (-5 to 256) by making them singletons:

Your answer is correct. The is operator compares the identity of two objects. The == operator compares the values of two objects.

An object's identity never changes once it has been created; you may think of it as the object's address in memory.

You can control comparison behaviour of object values by defining a __cmp__ method or a rich comparison method like __eq__.

is tests for identity == tests for equality

Each (small) integer value is mapped to a single value, so every 3 is identical and equal. This is an implementation detail, not part of the language spec though

Have a look at Stack Overflow question Python's “is” operator behaves unexpectedly with integers.

What it mostly boils down to is that "is" checks to see if they are the same object, not just equal to each other (the numbers below 256 are a special case).

As John Feminella said, most of the time you will use == and != because your objective is to compare values. I'd just like to categorise what you would do the rest of the time:

There is one and only one instance of NoneType i.e. None is a singleton. Consequently foo == None and foo is None mean the same. However the is test is faster and the Pythonic convention is to use foo is None.

If you are doing some introspection or mucking about with garbage collection or checking whether your custom-built string interning gadget is working or suchlike, then you probably have a use-case for foo is bar.

True and False are also (now) singletons, but there is no use-case for foo == True and no use case for foo is True.

While all these answers that rely on the implementation of objection pointer comparison vs value comparison are likely correct, there is a deeper syntactical reason for using is to determine if a variable value is None (in boolean logic often represented as NULL).

In relational database and other logic systems, NULL implies that the actual value is "unknown". Thus the logical expression xx == NULL must always evaluate to NULL itself, as it is impossible to ever know if xx, whatever value it may have, is the same as the unknown value. In programming languages that adhere more strictly to the rules of boolean logic, xx == NULL (or Pythonically xx == None) correctly evaluates to NULL, and alternative means must be provided to determine if a variable value is NULL. Python is an outlier in this regard, due to the unitary nature of the object reference to None. But for clarity and logical correctness, using the Python is comparison operator seems to me much sounder practice.

Category: python Time: 2008-09-25 Views: 3

Related post

iOS development

Android development

Python development

JAVA development

Development language

PHP development

Ruby development


Front-end development


development tools

Open Platform

Javascript development

.NET development

cloud computing


Copyright (C), All Rights Reserved.

processed in 0.161 (s). 12 q(s)