39

I was quite surprised when

[] is not []

evaluated to True.

What is happening in this code? What really not and is statements are doing?

martineau
  • 119,623
  • 25
  • 170
  • 301
fjsj
  • 10,995
  • 11
  • 41
  • 57

7 Answers7

60

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).

Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
36

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.

unholysampler
  • 17,141
  • 7
  • 47
  • 64
25

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
Jiaaro
  • 74,485
  • 42
  • 169
  • 190
  • 1
    Excellent answer, but, after reading [this](http://docs.python.org/release/2.7.3/reference/expressions.html#id26) in Python reference, I get confused: _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._ – auraham Aug 04 '12 at 03:50
  • "..so if you add something to x, it does not appear in y" - that seems wrong to me. Try `a="test";b="test";a is b`. It will give you `True` even though changing one will not change the other. – Pithikos Sep 29 '14 at 21:00
  • 5
    @Pithikos that is the because of an optimization in the particular version of python you are using, it is not a guarantee. Also, strings are immutable so you cannot change one of those values. you can only assign a new string to the same variable. – Jiaaro Sep 30 '14 at 13:50
8

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.

Sjoerd
  • 74,049
  • 16
  • 131
  • 175
3

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.

Wayne Werner
  • 49,299
  • 29
  • 200
  • 290
  • `a = b`. I believe that we are now guaranteed that `a is b`. – recursive Sep 15 '10 at 14:38
  • @recursive, do you know if that's the case for strings/numbers? – Wayne Werner Sep 16 '10 at 13:59
  • As far as I know, it's true for everything. When you assign `b` to `a` in python, you are assigning `a` to be a reference to the object currently referenced by `b`. So their identity will be identical. It's python, so it may be possible to do some weird thing like overriding assignment to break this, but in general, I'd say yes. – recursive Sep 16 '10 at 14:09
  • I guess that makes sense - and is different from `a = "hi"; b = "hi"` which `is` behavior is *not* guaranteed aside from returning True or False. – Wayne Werner Sep 16 '10 at 14:30
  • When I execute this `[] and []` evaluates to `[]`...what does that mean? – auraham Aug 03 '12 at 20:50
2

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
Gaurang Shah
  • 11,764
  • 9
  • 74
  • 137
0

@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.

nauer
  • 690
  • 5
  • 14