How does python evaluate "is" expressions? [duplicate] - python

This question already has answers here:
"is" operator behaves unexpectedly with integers
(11 answers)
Closed 9 years ago.
Erratic behavior of "is" expressions in python.
>>> 258 -1 is 257
False
And
>>> 258 -1 == 257
True
How is python evaluating "is" expression ? and why does it show it as false , eventhough it is true ?
Why is it happening only to certain set of numbers ?
2 - 1 is 1
True
works perfectly fine.

is is used for identity check, to check if both variables point to the same object,
while == is used for checking values.
From the docs:
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. x is not y yields the
inverse truth value.
>>> id(1000-1) == id(999)
False
""" What is id?
id(object) -> integer
Return the identity of an object. This is guaranteed to be unique among
simultaneously existing objects. (Hint: it's the object's memory address.)
"""
>>> 1000-1 is 999
False
>>> 1000-1 == 999
True
>>> x = [1]
>>> y = x #now y and x both point to the same object
>>> y is x
True
>>> id(y) == id(x)
True
>>> x = [1]
>>> y = [1]
>>> x == y
True
>>> x is y
False
>>> id(x),id(y) #different IDs
(161420364, 161420012)
But some small integers(-5 to 256) and small strings are cached by Python: Why (0-6) is -6 = False?
#small strings
>>> x = "foo"
>>> y = "foo"
>>> x is y
True
>>> x == y
True
#huge string
>>> x = "foo"*1000
>>> y = "foo"*1000
>>> x is y
False
>>> x==y
True

is compares object identity and yields True only if both sides are the same object. For performance reasons, Python maintains a "cache" of small integers and reuses them, so all int(1) objects are the same object. In CPython, cached integers range from -5 to 255, but this is an implementation detail, so you should not rely on it. If you want to compare equality, use ==, not is.

The is operator checks for object identity: the object created by calling 258-1 is NOT the same object as the one created by 257. The == operator checks if the values of the compared objects are the same.
Try using help('is').

The Python is operator checks for object identity, not object value. The two integers must refer to the same actual object internally for is to return true.
This will return true for "small" integers due to an internal cache maintained by Python, but two numbers with the same value will not return true if compared with is in general.

Related

Looking for an explanation on the results of identity testing on integer variables in Python [duplicate]

This question already has an answer here:
What's with the integer cache maintained by the interpreter?
(1 answer)
Closed 3 years ago.
I have a simple code I stumbled upon on HyperSkill and was testing it on the Python console, both Python2 and Python3. The results confused me.
>>> a = 5
>>> b = 5
>>> a == b
True
>>> a is b
True
>>> x = 1000
>>> y = 1000
>>> x == y
True
>>> x is y
False
>>>
I don't understand why the result of a is b is True and yet the result of x is y is (as expected) False
The is operator compares whether two objects are assigned to the same underlying object in memory. The == operator compares whether two objects have the equivalent value.
Small integer values (-5 to 256) are stored in memory in Python for efficiency. Assigning a variable to be one of those value integers will always assign it to the same underlying object in Python's memory. For larger values, a new object is created.
Here is some code to show it:
for x, y in zip(range(-7,260), range(-7,260)):
print(x, x is y)
# prints:
-7 False
-6 False
-5 True
-4 True
-3 True
-2 True
-1 True
0 True
1 True
2 True
...
254 True
255 True
256 True
257 False
258 False
259 False

Why does this str strict comparison fail in Python? [duplicate]

This question already has answers here:
Why does comparing strings using either '==' or 'is' sometimes produce a different result?
(15 answers)
Closed 8 years ago.
I have this code in a decorator:
is_local_valid = ['system_id', 'server_id', 'sensor_id']
local_params = [x for x in is_local_valid if x in kwargs.keys() and kwargs[x].lower() is 'local'] + [y for y in args if y.lower() is 'local']
if local_params == []:
raise AssertionError("Tried to access the database from a non connected profile")
I noticed that the is infix operator for comparing two strings returns False in this case, even when kwargs[x].lower() equals to local. The == operator does return True, though. Both are str, of course.
Any clue on what's going on?
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. x is not y yields the inverse truth value.
>>> id('local')
42745112
>>> a = {1: 'locAl'}
>>> id(a[1].lower())
53363408
They are not the same object
a is b determines whether two names a and b reference the same object (i.e. id(a) == id(b)). a == b determines whether they have equal values. It is rarely a good idea to compare strings with is; use == instead:
>>> "".join("hello")
'hello'
>>> "hello" is "".join("hello")
False
>>> "hello" == "".join("hello")
True
The only general case for comparison with is would be for None, e.g.:
if a is None:

How does "is" work in python?

Can please someone explain how one may use 'is' in an 'if' condition. I am working with the fractions module, and I'm having some trouble:
>>> Fraction(0, 1) is 0
False
>>> float(Fraction(0, 1))
0.0
>>> float(Fraction(0,1)) is 0.0
False
The only thing I found to work is:
>>> F = Fraction(a,b)
>>> if F >= 0:
... if F(0, 1) <= 0:
... ...
Is there a way to use 'is' here? Thanks.
The is operator in python is used to check if two variables are pointing to the very same object and is not meant to be used to check about numeric equality. You should use == for that instead.
For example consider that
(1000 + 1000) is (1000 + 1000)
returns False.
From the documentation:
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. x is not y yields the inverse truth value.
What you want here is ==, to test whether two objects are equal or equivalent by comparing the values and not the identities.
A trivial example (in CPython that may differ in other implementations):
>>> 1 + 2 == 3.0
True
>>> 1 + 2 is 3.0
False
>>> 1 + 2 is 3
True
>>> id(1 + 2)
4298185512
>>> id(3.0)
4298194656
>>> id(3)
4298185512
is checks for object identity. It returns true if two names refer to the same object. One typical usecase is to check if a name refers to None:
if foo is None:
# do stuff
a is b is equivalent to id(a) == id(b)
Quote from http://docs.python.org/library/operator.html:
operator.is_(a, b) Return a is b.
Tests object identity.

Python - comparing long/integer values with == and is [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Python “is” operator behaves unexpectedly with integers
Ran into something odd last night where doing
if max_urls is 0:
max_urls = 10
would always return false... even when max_urls was 0.... it was getting assigned from the database. When I did a
print type(max_urls)
would return
<type 'long'> 0
which seemed right but it would always return false.
If I changed it to
if max_urls == 0:
max_urls = 10
then finally it would return true when it was 0. Why the difference between == and is?
== is a value comparison, is is an object identity (memory location) comparison. You will often see that comparisons like max_urls is 0 will give the intended result because small values are usually cached in Python, but you always want to be using == instead of is when checking equality because this behavior cannot be relied upon.
Here is a brief example illustrating this:
>>> a = 0
>>> (a == 0, a is 0)
(True, True)
>>> a = 1000
>>> (a == 1000, a is 1000)
(True, False)
The is operator checks that two references point to the same object. You are testing if long(0) is the same object as int(0), and the answer is no. This will be crystal clear if you print their object ids:
>>> max_urls = long(0)
>>> id(max_urls)
335952
>>> id(0)
8402324
== on the other hand checks that two values are equivalent, even if they are not the exact same object. For instance:
>>> a = 777
>>> b = 777
>>> a is b
False
>>> a == b
True
>>> id(a)
8404568
>>> id(b)
8404640
Note: It is important that I used 777 and not a smaller number like 1 or 2. Quoting from the Python manual:
The current implementation keeps an array of integer objects for all integers between -5 and 256, when you create an int in that range you actually just get back a reference to the existing object.

"is" operator result: What is happening? [duplicate]

This question already has answers here:
Understanding the "is" operator [duplicate]
(11 answers)
Closed 3 years ago.
I was quite surprised when
[] is not []
evaluated to True.
What is happening in this code? What really not and is statements are doing?
a is not b is a special operator which is equivalent to not a is b.
The operator a is b returns True if a and b are bound to the same object, otherwise False. When you create two empty lists you get two different objects, so is returns False (and therefore is not returns True).
is is the identity comparison.
== is the equality comparison.
Your statement is making two different lists and checking if they are the same instance, which they are not. If you use == it will return true and because they are both empty lists.
The best way to describe WHY that happens is this:
Here is your example
>>> x = []
>>> y = []
>>> print(x is y)
... False
x and y are actually two different lists, so if you add something to x, it does not appear in y
>>> x.append(1)
>>> print(x)
... [1]
>>> print(y)
... []
So how do we make (x is y) evaluate true?
>>> x = []
>>> y = x
>>> print(x is y)
... True
>>> x.append(10)
>>> print(x)
... [10]
>>> print(y)
... [10]
>>> print(x is y)
... True
if you want to see if two lists have the same contents...
>>> x = []
>>> y = []
>>> print(x == y)
... True
>>> x.append(21)
>>> print(x)
... [21]
>>> print(y)
... []
>>> print(x == y)
... False
>>> y = [21]
>>> print(x == y)
... True
is means is same instance. It evaluates to true if the variables on either side of the operator point to the same object and false otherwise.
Reference, near the bottom.
is checks for identity. [] and [] are two different (but equivalent) lists. If you want to check if both the lists are empty you can use their truth value (false for empty strings, collections, and zeros).
if not ([] and []):
print 'Spanish Inquisition'
the only time that is is guaranteed to return True is for singletons such as None. Like the Highlander, there can be only one instance of None in your program - every time you return None it's the very same "thing" as the none referred to if you type print None.
[], OTOH, is not guaranteed to be anything except an empty list and evaluate to False in a boolean context.
I know I am posting to a pretty old post. however, this might help someone stumble upon this like me.
"is" checks, whether a memory address is same or not, while "==" check if the value is same or not. Would be much clear from the following example
let's first talk about immutable objects, as it's easy to understand
# could be any immutable object
immutable_a = 10
immutable_b = 10
# prints address of a and b variable
print "address of a is %s" % id(immutable_a)
print "address of a is %s" % id(immutable_b)
# as both addresses is same, following shall be true
print immutable_a is immutable_b
# as the values are also same, following shall be true as well
print immutable_a == immutable_b
now let's talk about mutable objects
# could be any mutable object
mutable_a = [10]
mutable_b = [10]
# prints address of a and b variable
print "address of mutable_a is %s" % id(mutable_a)
print "address of mutable_b is %s" % id(mutable_b)
# as addresses are not same, following shall be false
print mutable_a is mutable_b
# as the values are same, following shall be true
print mutable_a == mutable_b
#Jiaaro is right. Using is with immutable data types is dangerous because it is not predictable because of Pythons interpreter optimization.
See this example:
10 * "a" is 10 * "a" # True
100 * "a" is 100 * "a" # False
In the second line it is faster to create a new object with a new id for the interpreter. So use the is operator only with mutable types.

Categories