In Python, what are the consequences of using is instead of '=='

Asked

Viewed 553 times

21

The two forms below return True, but what are the consequences of this in a more complex code?

>>> a = '2'
>>> a is '2'  
>>> True
>>> a == '2' 
>>> True

3 answers

29


The consequences depend on the purpose of the code. is and == are not synonyms, and cannot simply be exchanged as if they were.

What happens is that in many situations, the two return the same value when replaced, giving an erroneous illusion that they behave in the same way, but the nature of the comparisons is completely different.

  • The is checks whether the two names point to the same object stored in memory

    (Maria and Joana live in the same house, so they have the same address)

  • the == compares the contents stored in each of the two names, whether they point to the same object, or to different objects.

    (Maria’s house is identical to José’s house, same furniture, same color, etc)

It is very important that the differences between the two operators are taken into account so that the code behaves as expected. For this, a little more detailed explanation about each one:


The operator is:

In Python, the operator is is the comparator of instance of objects, not of values.

For example:

>>> x = [2, 3, 4]
>>> y = [2, 3, 4]
>>> x is y

Returns

False

because although the values are equal, they are completely different objects.


is and strings

Don’t be fooled by this example:

>>> x = "string"
>>> y = "string"
>>> x is y
True
>>> z = "str"+"ing"
>>> a is z
True

In this case, despite the impression of comparison with is behave identically to that made with ==, what is happening here is something else. Python is "smart" enough not to allocate repeated values several times string, then he points the name of the new object to the string already stored previously, effectively taking advantage of the already allocated data.

Strings should normally be compared with ==, unless you know exactly what you’re doing.


is and some whole

Look at the following example:

>>> x = 256
>>> y = 256
>>> x is y
True

>>> x = 257
>>> y = 257
>>> x is y
False

This is due to a peculiarity determined by implementation: when you use numbers from -5 to 256, Python already has an internal storage table, whose objects are already natively created and your ID is taken advantage of.


The operator ==:

The == is the value comparator, as in most languages. The object may be different, what matters for comparison is the value:

>>> x = 1278
>>> y = 1278
>>> x == y

Returns:

True


The function id():

If need be thresh a situation where the is does not behave as expected, you can use the function id() to get the internal ID of the objects, as in the following example:

>>> x = 257
>>> y = 257
>>> id(x)
12686128
>>> id(y)
12686140


Compared to None:

The None is a special object in Python, and represents the absence of value, in a way like null of some languages. Because it is an object that represents the absence, and not a value in itself, you should always use x is None and x is not None, and never x == None and x != None.

Attention with this special case:

if ( x is None ):

In this case, an experienced programmer in other languages might feel tempted to simply use if ( x ), imagining that the None would already be considered false. Just as the value comparison should not be used with the None, in the if the verification also requires the is None or is not None


Implementing comparison in classes:

The methods that implement comparison is and == in Python are respectively __is__ and __eq__, and in this case, the programmer must be fully aware of the differences mentioned above. Roughly, it is something in this line:

# O exemplo foi simplificado demasiadamente ;)
class X(object):
    def __eq__(self, other):
        return self.value == other
    def __is__(self, other):
        return self.value is other 

9

Bacco’s answer is supercomplet, but for those who want a more concise answer:

The is serves to compare if two things are exactly the same object in computer RAM memory.

Already the == makes a background comparison of the content of objects. So if two objects in different places in memory have the same content, the == will detect equality, while the is nay.

2

A code is worth a thousand words.

class Pessoa(object):
    def __init__(self, nome, idade):
        self.nome = nome
        self.idade = idade

joao = Pessoa("João Bom de Python", 16) # 0x1
alex = Pessoa("Alex Java", 23) # 0x2
clone_alex = alex # 0x2

print joao is alex # 0x1 == 0x2
print clone_alex is alex # 0x2 == 0x2

One more, I’m excited:

>>> x = [1, 2, 3] # 0xC
>>> y = [1, 2, 3] # 0x18
>>> x is y # 0xC == 0x18
False
>>> x = y
>>> x is y # 0x18 == 0x18
True

Note: Addresses are only examples.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.