Comparing "float('nan')" and "math.nan" - python

I have a float variable which may or may not be a number, and I want to check if that is the case. With x = float('nan'), I observed some behavior that surprised me:
print(x is math.nan)
>>> False
This means that float('nan') and math.nan are different objects, which I didn't expect, but that's okay. However, the result is the same, when I check for equality with ==:
print(x == math.nan):
>>> False
I get the correct result for all kinds of not-a-number, if I use math.isnan(x). Still, why doesn't float('nan') == math.nan evaluate to True?.

"Not a number" is (in some sense) the absence of a value.
Traditionally, and per the IEEE floating-point specification, it does not equal itself.
That's because there is no meaningful value to compare.
In fact, some people use this fact to detect NaN, so you could try x != x as your condition instead (though the linked Q&A arguably has some better suggestions).
The expression math.nan is math.nan is true, though, because is does an object identity comparison rather than a value equivalence/equality comparison.

This is not special behaviour: is returns whether two object are actually referring to the same thing (essentially in memory) and == returns whether two objects have the same value.
To see if they refer to the same thing, we can use id().
>>> a = [1,2,3]
>>> b = a
>>> id(a)
140302781856200
>>> id(b)
140302781856200
>>> a == b
True
>>> a is b
True
>>> c = [1,2,3]
>>> id(c)
140302781864904
>>> a == c
True
>>> a is c
False
Here we see that by assigning b = a, they now refer to the same list: hence is and == are True. However when we define c to be a new variable with the same value as a and b, it is ==, but is returns False.
The same is true for NaNs.

That is because NaN is just a float value. Using is doesn't check for whether the variables have the same value, it checks whether they are the same object. If you create two floats with the same value, they are not the same object, they are two objects with the same value. Take this for example:
>>> a = float('nan')
>>> b = float('nan')
>>> a is b
False
So even if you create two NaN values the same way, they are not the same object. This is true even for more trivial floats. Try this:
>>> a = 1.
>>> b = 1.
>>> a is b
False
The default version of Python re-uses some values, so that any instance of that value is the same object. So take this for example (note the lack of decimal, these are integers not floats):
>>> a = 1
>>> b = 1
>>> a is b
True
But that is an implementation detail you should never rely on, it can change at any time and can vary between python implementations. But even with that, NaN is not one of the values the default Python interpreter does this for.
You can check whether two variables are the same object manually using the id function, which gives a unique number for each simultaneously-existing object (although the numbers can be re-used if a variable is deleted, even automatically).
>>> a=1.
>>> b=1.
>>> c=float('nan')
>>> d=float('nan')
>>> e=1
>>> f=1
>>> id(a)
139622774035752
>>> id(b)
139622774035872
>>> id(c)
139622774035824
>>> id(d)
139622774035800
>>> id(e)
139622781650528
>>> id(f)
139622781650528
As for why they aren't equal, that is just part of the definition of NaN as it is used on modern computers. By definition, NaN must never be equal to itself. It is part of an international standard on how floating-point numbers work, and this behavior is built into modern CPUs.

While they are not the same object (because they are from different modules where they were implemented separately) and they are not equal (by design NaN != NaN), there is the function math.isnan (and numpy.isnan if you want a vectorized version) exactly for this purpose:
import math
import numpy
math.isnan(math.nan)
# True
math.isnan(numpy.nan)
# True
math.isnan(float("nan"))
# True
Although they are all unequal to each other and not identical:
math.nan == numpy.nan or math.nan is numpy.nan
# False
math.nan == float("nan") or math.nan is float("nan")
# False
numpy.nan == float("nan") or numpy.nan is float("nan")
# False

You can use the "hex" function that is built into "float"
float('nan') == math.nan # FALSE
float('nan').hex() == math.nan.hex() # TRUE
float('nan').hex() == float('nan').hex() # TRUE
float('nan').hex() == numpy.nan.hex() # TRUE
This is very helpful if you are using queries in pandas. I recently was trying to use:
df.eval('A == "NaN"')
Which should check if column A is NaN. But, pandas was automatically converting the string, "NaN", into a float. Most people would recommend using df['A'].isna(), but in our case, trying to pass an expression into a method, so it should handle any expression.
The solution was to do:
df.applymap(lambda x: 'NaN' if x.hex() == float('NaN').hex() else x).eval('A == "NaN"')

You can convert the nan value to string for comparing.
somthing like this:
x=float("nan")
s_nan = str(x)
if s_nan == "nan":
# What you need to do...
print('x is not a number')

Related

Division and == in python, why gives different answers [duplicate]

This question's answers are a community effort. Edit existing answers to improve this post. It is not currently accepting new answers or interactions.
My Google-fu has failed me.
In Python, are the following two tests for equality equivalent?
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 (in memory), == if the objects referred to by the variables are equal.
>>> a = [1, 2, 3]
>>> b = a
>>> b is a
True
>>> b == a
True
# Make a new copy of list `a` via the slice operator,
# and assign it to variable `b`
>>> b = a[:]
>>> b is a
False
>>> b == a
True
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
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
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
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.
Is there a difference between == and is in Python?
Yes, they have a very important difference.
==: check for equality - the semantics are that equivalent objects (that aren't necessarily the same object) will test as equal. As the documentation says:
The operators <, >, ==, >=, <=, and != compare the values of two objects.
is: check for identity - the semantics are that the object (as held in memory) is the object. Again, the documentation says:
The operators is and is not test for object identity: x is y is true
if and only if x and y are the same object. Object identity is
determined using the id() function. x is not y yields the inverse
truth value.
Thus, the check for identity is the same as checking for the equality of the IDs of the objects. That is,
a is b
is the same as:
id(a) == id(b)
where id is the builtin function that returns an integer that "is guaranteed to be unique among simultaneously existing objects" (see help(id)) and where a and b are any arbitrary objects.
Other Usage Directions
You should use these comparisons for their semantics. Use is to check identity and == to check equality.
So in general, we use is to check for identity. This is usually useful when we are checking for an object that should only exist once in memory, referred to as a "singleton" in the documentation.
Use cases for is include:
None
enum values (when using Enums from the enum module)
usually modules
usually class objects resulting from class definitions
usually function objects resulting from function definitions
anything else that should only exist once in memory (all singletons, generally)
a specific object that you want by identity
Usual use cases for == include:
numbers, including integers
strings
lists
sets
dictionaries
custom mutable objects
other builtin immutable objects, in most cases
The general use case, again, for ==, is the object you want may not be the same object, instead it may be an equivalent one
PEP 8 directions
PEP 8, the official Python style guide for the standard library also mentions two use-cases for is:
Comparisons to singletons like None should always be done with is or
is not, never the equality operators.
Also, beware of writing if x when you really mean if x is not None --
e.g. when testing whether a variable or argument that defaults to None
was set to some other value. The other value might have a type (such
as a container) that could be false in a boolean context!
Inferring equality from identity
If is is true, equality can usually be inferred - logically, if an object is itself, then it should test as equivalent to itself.
In most cases this logic is true, but it relies on the implementation of the __eq__ special method. As the docs say,
The default behavior for equality comparison (== and !=) is based on
the identity of the objects. Hence, equality comparison of instances
with the same identity results in equality, and equality comparison of
instances with different identities results in inequality. A
motivation for this default behavior is the desire that all objects
should be reflexive (i.e. x is y implies x == y).
and in the interests of consistency, recommends:
Equality comparison should be reflexive. In other words, identical
objects should compare equal:
x is y implies x == y
We can see that this is the default behavior for custom objects:
>>> class Object(object): pass
>>> obj = Object()
>>> obj2 = Object()
>>> obj == obj, obj is obj
(True, True)
>>> obj == obj2, obj is obj2
(False, False)
The contrapositive is also usually true - if somethings test as not equal, you can usually infer that they are not the same object.
Since tests for equality can be customized, this inference does not always hold true for all types.
An exception
A notable exception is nan - it always tests as not equal to itself:
>>> nan = float('nan')
>>> nan
nan
>>> nan is nan
True
>>> nan == nan # !!!!!
False
Checking for identity can be much a much quicker check than checking for equality (which might require recursively checking members).
But it cannot be substituted for equality where you may find more than one object as equivalent.
Note that comparing equality of lists and tuples will assume that identity of objects are equal (because this is a fast check). This can create contradictions if the logic is inconsistent - as it is for nan:
>>> [nan] == [nan]
True
>>> (nan,) == (nan,)
True
A Cautionary Tale:
The question is attempting to use is to compare integers. You shouldn't assume that an instance of an integer is the same instance as one obtained by another reference. This story explains why.
A commenter had code that relied on the fact that small integers (-5 to 256 inclusive) are singletons in Python, instead of checking for equality.
Wow, this can lead to some insidious bugs. I had some code that checked if a is b, which worked as I wanted because a and b are typically small numbers. The bug only happened today, after six months in production, because a and b were finally large enough to not be cached. – gwg
It worked in development. It may have passed some unittests.
And it worked in production - until the code checked for an integer larger than 256, at which point it failed in production.
This is a production failure that could have been caught in code review or possibly with a style-checker.
Let me emphasize: do not use is to compare integers.
== determines if the values are equal, while is determines if they are the exact same object.
What's the difference between is and ==?
== and is are different comparison! As others already said:
== compares the values of the objects.
is compares the references of the objects.
In Python names refer to objects, for example in this case value1 and value2 refer to an int instance storing the value 1000:
value1 = 1000
value2 = value1
Because value2 refers to the same object is and == will give True:
>>> value1 == value2
True
>>> value1 is value2
True
In the following example the names value1 and value2 refer to different int instances, even if both store the same integer:
>>> value1 = 1000
>>> value2 = 1000
Because the same value (integer) is stored == will be True, that's why it's often called "value comparison". However is will return False because these are different objects:
>>> value1 == value2
True
>>> value1 is value2
False
When to use which?
Generally is is a much faster comparison. That's why CPython caches (or maybe reuses would be the better term) certain objects like small integers, some strings, etc. But this should be treated as implementation detail that could (even if unlikely) change at any point without warning.
You should only use is if you:
want to check if two objects are really the same object (not just the same "value"). One example can be if you use a singleton object as constant.
want to compare a value to a Python constant. The constants in Python are:
None
True1
False1
NotImplemented
Ellipsis
__debug__
classes (for example int is int or int is float)
there could be additional constants in built-in modules or 3rd party modules. For example np.ma.masked from the NumPy module)
In every other case you should use == to check for equality.
Can I customize the behavior?
There is some aspect to == that hasn't been mentioned already in the other answers: It's part of Pythons "Data model". That means its behavior can be customized using the __eq__ method. For example:
class MyClass(object):
def __init__(self, val):
self._value = val
def __eq__(self, other):
print('__eq__ method called')
try:
return self._value == other._value
except AttributeError:
raise TypeError('Cannot compare {0} to objects of type {1}'
.format(type(self), type(other)))
This is just an artificial example to illustrate that the method is really called:
>>> MyClass(10) == MyClass(10)
__eq__ method called
True
Note that by default (if no other implementation of __eq__ can be found in the class or the superclasses) __eq__ uses is:
class AClass(object):
def __init__(self, value):
self._value = value
>>> a = AClass(10)
>>> b = AClass(10)
>>> a == b
False
>>> a == a
So it's actually important to implement __eq__ if you want "more" than just reference-comparison for custom classes!
On the other hand you cannot customize is checks. It will always compare just if you have the same reference.
Will these comparisons always return a boolean?
Because __eq__ can be re-implemented or overridden, it's not limited to return True or False. It could return anything (but in most cases it should return a boolean!).
For example with NumPy arrays the == will return an array:
>>> import numpy as np
>>> np.arange(10) == 2
array([False, False, True, False, False, False, False, False, False, False], dtype=bool)
But is checks will always return True or False!
1 As Aaron Hall mentioned in the comments:
Generally you shouldn't do any is True or is False checks because one normally uses these "checks" in a context that implicitly converts the condition to a boolean (for example in an if statement). So doing the is True comparison and the implicit boolean cast is doing more work than just doing the boolean cast - and you limit yourself to booleans (which isn't considered pythonic).
Like PEP8 mentions:
Don't compare boolean values to True or False using ==.
Yes: if greeting:
No: if greeting == True:
Worse: if greeting is True:
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. This behavior is totally implementation-dependent and not guaranteed to be preserved under all manner of minor transformative operations.
For example, Python 3.5 also makes short strings singletons, but slicing them disrupts this behavior:
>>> "foo" + "bar" == "foobar"
True
>>> "foo" + "bar" is "foobar"
True
>>> "foo"[:] + "bar" == "foobar"
True
>>> "foo"[:] + "bar" is "foobar"
False
https://docs.python.org/library/stdtypes.html#comparisons
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
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__.
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).
In a nutshell, is checks whether two references point to the same object or not.== checks whether two objects have the same value or not.
a=[1,2,3]
b=a #a and b point to the same object
c=list(a) #c points to different object
if a==b:
print('#') #output:#
if a is b:
print('##') #output:##
if a==c:
print('###') #output:##
if a is c:
print('####') #no output as c and a point to different object
As the other people in this post answer the question in details the difference between == and is for comparing Objects or variables, I would emphasize mainly the comparison between is and == for strings which can give different results and I would urge programmers to carefully use them.
For string comparison, make sure to use == instead of is:
str = 'hello'
if (str is 'hello'):
print ('str is hello')
if (str == 'hello'):
print ('str == hello')
Out:
str is hello
str == hello
But in the below example == and is will get different results:
str2 = 'hello sam'
if (str2 is 'hello sam'):
print ('str2 is hello sam')
if (str2 == 'hello sam'):
print ('str2 == hello sam')
Out:
str2 == hello sam
Conclusion and Analysis:
Use is carefully to compare between strings.
Since is for comparing objects and since in Python 3+ every variable such as string interpret as an object, let's see what happened in above paragraphs.
In python there is id function that shows a unique constant of an object during its lifetime. This id is using in back-end of Python interpreter to compare two objects using is keyword.
str = 'hello'
id('hello')
> 140039832615152
id(str)
> 140039832615152
But
str2 = 'hello sam'
id('hello sam')
> 140039832615536
id(str2)
> 140039832615792
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.
Most of them already answered to the point. Just as an additional note (based on my understanding and experimenting but not from a documented source), the statement
== if the objects referred to by the variables are equal
from above answers should be read as
== if the objects referred to by the variables are equal and objects belonging to the same type/class
. I arrived at this conclusion based on the below test:
list1 = [1,2,3,4]
tuple1 = (1,2,3,4)
print(list1)
print(tuple1)
print(id(list1))
print(id(tuple1))
print(list1 == tuple1)
print(list1 is tuple1)
Here the contents of the list and tuple are same but the type/class are different.

why string multiplied by and integer and variable multiplied by integer is not same? [duplicate]

This question's answers are a community effort. Edit existing answers to improve this post. It is not currently accepting new answers or interactions.
My Google-fu has failed me.
In Python, are the following two tests for equality equivalent?
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 (in memory), == if the objects referred to by the variables are equal.
>>> a = [1, 2, 3]
>>> b = a
>>> b is a
True
>>> b == a
True
# Make a new copy of list `a` via the slice operator,
# and assign it to variable `b`
>>> b = a[:]
>>> b is a
False
>>> b == a
True
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
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
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
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.
Is there a difference between == and is in Python?
Yes, they have a very important difference.
==: check for equality - the semantics are that equivalent objects (that aren't necessarily the same object) will test as equal. As the documentation says:
The operators <, >, ==, >=, <=, and != compare the values of two objects.
is: check for identity - the semantics are that the object (as held in memory) is the object. Again, the documentation says:
The operators is and is not test for object identity: x is y is true
if and only if x and y are the same object. Object identity is
determined using the id() function. x is not y yields the inverse
truth value.
Thus, the check for identity is the same as checking for the equality of the IDs of the objects. That is,
a is b
is the same as:
id(a) == id(b)
where id is the builtin function that returns an integer that "is guaranteed to be unique among simultaneously existing objects" (see help(id)) and where a and b are any arbitrary objects.
Other Usage Directions
You should use these comparisons for their semantics. Use is to check identity and == to check equality.
So in general, we use is to check for identity. This is usually useful when we are checking for an object that should only exist once in memory, referred to as a "singleton" in the documentation.
Use cases for is include:
None
enum values (when using Enums from the enum module)
usually modules
usually class objects resulting from class definitions
usually function objects resulting from function definitions
anything else that should only exist once in memory (all singletons, generally)
a specific object that you want by identity
Usual use cases for == include:
numbers, including integers
strings
lists
sets
dictionaries
custom mutable objects
other builtin immutable objects, in most cases
The general use case, again, for ==, is the object you want may not be the same object, instead it may be an equivalent one
PEP 8 directions
PEP 8, the official Python style guide for the standard library also mentions two use-cases for is:
Comparisons to singletons like None should always be done with is or
is not, never the equality operators.
Also, beware of writing if x when you really mean if x is not None --
e.g. when testing whether a variable or argument that defaults to None
was set to some other value. The other value might have a type (such
as a container) that could be false in a boolean context!
Inferring equality from identity
If is is true, equality can usually be inferred - logically, if an object is itself, then it should test as equivalent to itself.
In most cases this logic is true, but it relies on the implementation of the __eq__ special method. As the docs say,
The default behavior for equality comparison (== and !=) is based on
the identity of the objects. Hence, equality comparison of instances
with the same identity results in equality, and equality comparison of
instances with different identities results in inequality. A
motivation for this default behavior is the desire that all objects
should be reflexive (i.e. x is y implies x == y).
and in the interests of consistency, recommends:
Equality comparison should be reflexive. In other words, identical
objects should compare equal:
x is y implies x == y
We can see that this is the default behavior for custom objects:
>>> class Object(object): pass
>>> obj = Object()
>>> obj2 = Object()
>>> obj == obj, obj is obj
(True, True)
>>> obj == obj2, obj is obj2
(False, False)
The contrapositive is also usually true - if somethings test as not equal, you can usually infer that they are not the same object.
Since tests for equality can be customized, this inference does not always hold true for all types.
An exception
A notable exception is nan - it always tests as not equal to itself:
>>> nan = float('nan')
>>> nan
nan
>>> nan is nan
True
>>> nan == nan # !!!!!
False
Checking for identity can be much a much quicker check than checking for equality (which might require recursively checking members).
But it cannot be substituted for equality where you may find more than one object as equivalent.
Note that comparing equality of lists and tuples will assume that identity of objects are equal (because this is a fast check). This can create contradictions if the logic is inconsistent - as it is for nan:
>>> [nan] == [nan]
True
>>> (nan,) == (nan,)
True
A Cautionary Tale:
The question is attempting to use is to compare integers. You shouldn't assume that an instance of an integer is the same instance as one obtained by another reference. This story explains why.
A commenter had code that relied on the fact that small integers (-5 to 256 inclusive) are singletons in Python, instead of checking for equality.
Wow, this can lead to some insidious bugs. I had some code that checked if a is b, which worked as I wanted because a and b are typically small numbers. The bug only happened today, after six months in production, because a and b were finally large enough to not be cached. – gwg
It worked in development. It may have passed some unittests.
And it worked in production - until the code checked for an integer larger than 256, at which point it failed in production.
This is a production failure that could have been caught in code review or possibly with a style-checker.
Let me emphasize: do not use is to compare integers.
== determines if the values are equal, while is determines if they are the exact same object.
What's the difference between is and ==?
== and is are different comparison! As others already said:
== compares the values of the objects.
is compares the references of the objects.
In Python names refer to objects, for example in this case value1 and value2 refer to an int instance storing the value 1000:
value1 = 1000
value2 = value1
Because value2 refers to the same object is and == will give True:
>>> value1 == value2
True
>>> value1 is value2
True
In the following example the names value1 and value2 refer to different int instances, even if both store the same integer:
>>> value1 = 1000
>>> value2 = 1000
Because the same value (integer) is stored == will be True, that's why it's often called "value comparison". However is will return False because these are different objects:
>>> value1 == value2
True
>>> value1 is value2
False
When to use which?
Generally is is a much faster comparison. That's why CPython caches (or maybe reuses would be the better term) certain objects like small integers, some strings, etc. But this should be treated as implementation detail that could (even if unlikely) change at any point without warning.
You should only use is if you:
want to check if two objects are really the same object (not just the same "value"). One example can be if you use a singleton object as constant.
want to compare a value to a Python constant. The constants in Python are:
None
True1
False1
NotImplemented
Ellipsis
__debug__
classes (for example int is int or int is float)
there could be additional constants in built-in modules or 3rd party modules. For example np.ma.masked from the NumPy module)
In every other case you should use == to check for equality.
Can I customize the behavior?
There is some aspect to == that hasn't been mentioned already in the other answers: It's part of Pythons "Data model". That means its behavior can be customized using the __eq__ method. For example:
class MyClass(object):
def __init__(self, val):
self._value = val
def __eq__(self, other):
print('__eq__ method called')
try:
return self._value == other._value
except AttributeError:
raise TypeError('Cannot compare {0} to objects of type {1}'
.format(type(self), type(other)))
This is just an artificial example to illustrate that the method is really called:
>>> MyClass(10) == MyClass(10)
__eq__ method called
True
Note that by default (if no other implementation of __eq__ can be found in the class or the superclasses) __eq__ uses is:
class AClass(object):
def __init__(self, value):
self._value = value
>>> a = AClass(10)
>>> b = AClass(10)
>>> a == b
False
>>> a == a
So it's actually important to implement __eq__ if you want "more" than just reference-comparison for custom classes!
On the other hand you cannot customize is checks. It will always compare just if you have the same reference.
Will these comparisons always return a boolean?
Because __eq__ can be re-implemented or overridden, it's not limited to return True or False. It could return anything (but in most cases it should return a boolean!).
For example with NumPy arrays the == will return an array:
>>> import numpy as np
>>> np.arange(10) == 2
array([False, False, True, False, False, False, False, False, False, False], dtype=bool)
But is checks will always return True or False!
1 As Aaron Hall mentioned in the comments:
Generally you shouldn't do any is True or is False checks because one normally uses these "checks" in a context that implicitly converts the condition to a boolean (for example in an if statement). So doing the is True comparison and the implicit boolean cast is doing more work than just doing the boolean cast - and you limit yourself to booleans (which isn't considered pythonic).
Like PEP8 mentions:
Don't compare boolean values to True or False using ==.
Yes: if greeting:
No: if greeting == True:
Worse: if greeting is True:
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. This behavior is totally implementation-dependent and not guaranteed to be preserved under all manner of minor transformative operations.
For example, Python 3.5 also makes short strings singletons, but slicing them disrupts this behavior:
>>> "foo" + "bar" == "foobar"
True
>>> "foo" + "bar" is "foobar"
True
>>> "foo"[:] + "bar" == "foobar"
True
>>> "foo"[:] + "bar" is "foobar"
False
https://docs.python.org/library/stdtypes.html#comparisons
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
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__.
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).
In a nutshell, is checks whether two references point to the same object or not.== checks whether two objects have the same value or not.
a=[1,2,3]
b=a #a and b point to the same object
c=list(a) #c points to different object
if a==b:
print('#') #output:#
if a is b:
print('##') #output:##
if a==c:
print('###') #output:##
if a is c:
print('####') #no output as c and a point to different object
As the other people in this post answer the question in details the difference between == and is for comparing Objects or variables, I would emphasize mainly the comparison between is and == for strings which can give different results and I would urge programmers to carefully use them.
For string comparison, make sure to use == instead of is:
str = 'hello'
if (str is 'hello'):
print ('str is hello')
if (str == 'hello'):
print ('str == hello')
Out:
str is hello
str == hello
But in the below example == and is will get different results:
str2 = 'hello sam'
if (str2 is 'hello sam'):
print ('str2 is hello sam')
if (str2 == 'hello sam'):
print ('str2 == hello sam')
Out:
str2 == hello sam
Conclusion and Analysis:
Use is carefully to compare between strings.
Since is for comparing objects and since in Python 3+ every variable such as string interpret as an object, let's see what happened in above paragraphs.
In python there is id function that shows a unique constant of an object during its lifetime. This id is using in back-end of Python interpreter to compare two objects using is keyword.
str = 'hello'
id('hello')
> 140039832615152
id(str)
> 140039832615152
But
str2 = 'hello sam'
id('hello sam')
> 140039832615536
id(str2)
> 140039832615792
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.
Most of them already answered to the point. Just as an additional note (based on my understanding and experimenting but not from a documented source), the statement
== if the objects referred to by the variables are equal
from above answers should be read as
== if the objects referred to by the variables are equal and objects belonging to the same type/class
. I arrived at this conclusion based on the below test:
list1 = [1,2,3,4]
tuple1 = (1,2,3,4)
print(list1)
print(tuple1)
print(id(list1))
print(id(tuple1))
print(list1 == tuple1)
print(list1 is tuple1)
Here the contents of the list and tuple are same but the type/class are different.

Precise Membership Test in Python

The in operator tests for equivalence using comparison, but Python's comparison isn't precise in the sense that True == 1 and 0 == False, yielding -
>>> True in [ 1 ]
True
>>> False in [ 0 ]
True
>>> 1 in [ True ]
True
>>> 0 in [ False ]
True
whereas I need a precise comparison (similar to === in other languages) that would yield False in all of the above examples. I could of course iterate over the list:
res = False
for member in mylist:
if subject == member and type( subject ) == type( member ):
res = True
break
This is obviously much less efficient then using the builtin in operator, even if I pack it as a list comprehension. Is there some native alternative to in such as a list method or some way to tweak in's behavior to get the required result?
The in operator is used in my case for testing the uniqueness of all list members, so a native uniqueness test would do as well.
Important note: The list may contain mutable values, so using set isn't an option.
Python version is 3.4, would be great for the solution to work on 2.7 too.
EDIT TO ALL THOSE WHO SUGGEST USING IS:
I look for a non-iterating, native alternative to a in b.
The is operator is not relevant for this case. For example, in the following situation in works just fine but is won't:
>>> [1,2] in [[1,2]]
True
Please, do read the question before answering it...
in doesn't test for equivalence at all. It checks if an item is in a container. Example:
>>> 5 in [1,2,3,4,5]
True
>>> 6 in [1,2,3,4,5]
False
>>> True in {True, False}
True
>>> "k" in ("b","c")
True
What you are looking for is is.
>>> True == 1
True
>>> True is 1
False
>>> False == 0
True
>>> False is 0
False
EDIT
After reading your edit, I don't think there is something built in in python libraries that suits your needs. What you want is basically to differentiate between int and bool (True, False). But python itself treats True and False as integers. This is because bool is a subclass of int. Which is why True == 1 and False==0 evaluates to true. You can even do:
>>> isinstance ( True, int)
True
I cannot think of anything better than your own solution, However, if your list is certain to contain any item not more than once you can use list.index()
try:
index_val = mylist.index(subject)
except ValueError:
index_val = None
if (index_val!=None):
return type(subject) == type(member)
Since index is built-in, it might be a little faster, though rather inelegant.
Python in operator is precise and the behavior you're complaining of is perfectly expected, since bool is a subclass of int.
Below is the excerpt of the official Python documentation describing the boolean type:
Booleans
These represent the truth values False and True. The two objects representing the values False and True are the only Boolean objects. The Boolean type is a subtype of plain integers, and Boolean values behave like the values 0 and 1, respectively, in almost all contexts, the exception being that when converted to a string, the strings "False" or "True" are returned, respectively.
You can also have a look at PEP 285.
You're looking for the is operator:
if any(x is True for x in l):
...
is, however, isn't exactly === from other languages. is checks identity, not just equality without type coercion. Since CPython uses string and integer interning, two objects that are equal may not be the same object:
In [19]: a = '12'
In [20]: b = '123'
In [21]: a += '3'
In [22]: a is b
Out[22]: False
In [23]: a == b
Out[23]: True
In [27]: 100001 is 100000 + 1
Out[27]: False
In [28]: 100001 == 100000 + 1
Out[28]: True
In Python 3, None, True, and False are essentially singletons, so using is for discerning True from 1 will work perfectly fine. In Python 2, however, this is possible:
In [29]: True = 1
In [31]: True is 1
Out[31]: True
Equality can be overridden __eq__ method, so you can define an object that is equal to any other object:
In [1]: %paste
class Test(object):
def __eq__(self, other):
return True
## -- End pasted text --
In [2]: x = Test()
In [3]: x == None
Out[3]: True
In [4]: x == True
Out[4]: True
In [5]: x == False
Out[5]: True
In this case, how would === work? There is no general solution, so Python has no built-in method of lists that does what you want.

Is it safe to replace '==' with 'is' to compare Boolean-values

I did several Boolean Comparisons:
>>> (True or False) is True
True
>>> (True or False) == True
True
It sounds like == and is are interchangeable for Boolean-values.
Sometimes it's more clear to use is
I want to know that:
Are True and False pre-allocated in python?
Is bool(var) always return the same True(or False) with the pre-allocated True(or False)?
Is it safe to replace == with is to compare Boolean-values?
It's not about Best-Practice.
I just want to know the Truth.
You probably shouldn't ever need to compare booleans. If you are doing something like:
if some_bool == True:
...
...just change it to:
if some_bool:
...
No is or == needed.
As commenters have pointed out, there are valid reasons to compare booleans. If both booleans are unknown and you want to know if one is equal to the other, you should use == or != rather than is or is not (the reason is explained below). Note that this is logically equivalent to xnor and xor respectively, which don't exist as logical operators in Python.
Internally, there should only ever be two boolean literal objects (see also the C API), and bool(x) is True should be True if bool(x) == True for any Python program. Two caveats:
This does not mean that x is True if x == True, however (eg. x = 1).
This is true for the usual implementation of Python (CPython) but might not be true in other implementations. Hence == is a more reliable comparison.
Watch out for what else you may be comparing.
>>> 1 == True
True
>>> 1 is True
False
True and False will have stable object ids for their lifetime in your python instance.
>>> id(True)
4296106928
>>> id(True)
4296106928
is compares the id of an object
EDIT: adding or
Since OP is using or in question it may be worth pointing this out.
or that evaluates True: returns the first 'True' object.
>>> 1 or True
1
>>> 'a' or True
'a'
>>> True or 1
True
or that evaluates False: returns the last 'False' object
>>> False or ''
''
>>> '' or False
False
and that evaluates to True: returns the last 'True' object
>>> True and 1
1
>>> 1 and True
True
and that evaluates to False: returns the first 'False' object
>>> '' and False
''
>>> False and ''
False
This is an important python idiom and it allows concise and compact code for dealing with boolean logic over regular python objects.
>>> bool([])
False
>>> bool([0])
True
>>> bool({})
False
>>> bool({False: False})
True
>>> bool(0)
False
>>> bool(-1)
True
>>> bool('False')
True
>>> bool('')
False
Basically 'empty' objects are False, 'non empty' are True.
Combining this with #detly's and the other answers should provide some insight into how to use if and bools in python.
Yes. There are guaranteed to be exactly two bools, True and False:
Class bool cannot be subclassed
further. Its only instances are False
and True.
That means if you know both operands are bool, == and is are equivalent. However, as detly notes, there's usually no reason to use either in this case.
It seems that all answers deal with True and False as defined after an interpreter startup. Before booleans became part of Python they were often defined as part of a program. Even now (Python 2.6.6) they are only names that can be pointed to different objects:
>>> True = 1
>>> (2 > 1)
True
>>> (2 > 1) == True
True
>>> (2 > 1) is True
False
If you have to deal with older software, be aware of that.
The == operator tests for equality The is keyword tests for object identity. Whether we are talking about the same object. Note, that more variables may refer to the same object.
== and is are both comparison operators, which would return a boolean value - True or False. True has a numeric value of 1 and False has a numeric value of 0.
The operator == compare the values of two objects and objects compared are most often are the same types (int vs int, float vs float), If you compare objects of different types, then they are unequal. The operator is tests for object identity, 'x is y' is true if both x and y have the same id. That is, they are same objects.
So, when you are comparing if you comparing the return values of same type, use == and if you are comparing if two objects are same (be it boolean or anything else), you can use is.
42 is 42 is True and is same as 42 == 42.
Another reason to compare values using == is that both None and False are “falsy” values. And sometimes it’s useful to use None to mark a value as “not defined” or “no value” while considering True and False values to work with:
def some_function(val = None):
"""This function does an awesome thing."""
if val is None:
# Values was not defined.
elif val == False:
# User passed boolean value.
elif val == True:
# User passed boolean value.
else:
# Quack quack.
Somewhat related question: Python != operation vs “is not”.

Strange Python behavior from inappropriate usage of 'is not' comparison?

I (incorrectly?) used 'is not' in a comparison and found this curious behavior:
>>> a = 256
>>> b = int('256')
>>> c = 300
>>> d = int('300')
>>>
>>> a is not b
False
>>> c is not d
True
Obviously I should have used:
>>> a != b
False
>>> c != d
False
But it worked for a long time due to small-valued test-cases until I happened to
use a number of 495.
If this is invalid syntax, then why? And shouldn't I at least get a warning?
"is" is not a check of equality of value, but a check that two variables point to the same instance of an object.
ints and strings are confusing for this as is and == can happen to give the same result due to how the internals of the language work.
For small numbers, Python is reusing the object instances, but for larger numbers, it creates new instances for them.
See this:
>>> a=256
>>> b=int('256')
>>> c=300
>>> d=int('300')
>>> id(a)
158013588
>>> id(b)
158013588
>>> id(c)
158151472
>>> id(d)
158151436
which is exactly why a is b, but c isn't d.
Don't use is [not] to compare integers; use == and != instead. Even though is works in current CPython for small numbers due to an optimization, it's unreliable and semantically wrong. The syntax itself is valid, but the benefits of a warning (which would have to be checked on every use of is and could be problematic with subclasses of int) are presumably not worth the trouble.
This is covered elsewhere on SO, but I didn't find it just now.
Int is an object in python, and python caches small integer between [-5,256] by default, so where you use int in [-5,256], they are identical.
a = 256
b = 256
a is b # True
If you declare two integers not in [-5,256], python will create two objects which are not the same(though they have the same value).
a = 257
b = 257
a is b # False
In your case, using != instead to compare the value is the right way.
a = 257
b = 257
a != b # False
For more understanding why this occurs take a look to Python-2.6.5/Objects/intobject.c:78:small_ints array and Python-2.6.5/Objects/intobject.c:1292:_PyInt_Init function in python sources.
Also similar thing occurs with lists:
>>> a = [12]
>>> id_a = id(a)
>>> del(a)
>>> id([1,2,34]) == id_a
True
>>>
Removed lists are not destroyed. They are reused

Categories

Resources