4

Note: Before you go and downvote or close my question, or mark it a duplicate, let me assure you that I have looked a dozens and dozens of similar questions on SO and Googled but after more than an hour, I still haven't solved this problem. No other answer solved my problem.

Question I have this Python code:

text = ''
text += '<' + '/' + '>'

print text, '</>'
print repr(text), repr('</>')

if text is '</>':
    print 'Equal'
else:
    print 'Not equal!'

I simply want to compare two strings. For some reason, I need to concatenate characters to text one by one. I expected the if-statement to evaluate to True but it doesn't. And I am at a loss why!

Here's the output:

</> </> '</>' '</>' Not equal!

I am new to Python, and am using Python 2.7. Can anybody help, please?

سیف خان
  • 181
  • 1
  • 1
  • 18
  • @gdlmx I must have been looking in wrong places then. Thank you. – سیف خان Apr 23 '16 at 23:21
  • I never thought to look for difference between `is` and `==`, which is why I never found this post. – سیف خان Apr 23 '16 at 23:22
  • 1
    `is` check for the object identity, that is the direction in memory of the object not the value they contain, for that use `==`. Only the build-in constants are guaranty to evaluate the same with `is` and `==` that is why you see will stuff like `a is None` more often that `a == None` because the former is more idiomatic. So unless you are checking for `None` or if they are located in the same place (aka the point to the same thing) in memory, use `==` – Copperfield Apr 23 '16 at 23:45

2 Answers2

13

You need to use == not is. is checks for object identity not equality.

e.g.

Let's say you have foo and bar:

>>> foo = 'green eggs and ham'
>>> bar = 'green eggs and ham'
>>> foo is bar
>>> False
>>> foo == bar
>>> True

On my machine:

>>> id(foo)
>>> 52008832 
>>> id(bar)
>>> 52010560

Now, check this out:

>>> foobar = bar
>>> foobar is bar
>>> True

This is true because we've aliased the variable foobar to point to bar which is a reference. Clearly, they reference the same location under this aliasing. Hence, is returns True.

More interestingly, consider two ints. This will only work for small ints (-5, 256).

>>> foo = 123
>>> bar = 123
>>> foo is bar
>>> True
>>> id(foo)
>>> 1993000432 # == id(bar)

ints (-5, 256) are cached and so ints within this range will eval to true using is for comparing object identity.

Pythonista
  • 11,152
  • 2
  • 29
  • 49
2

I have never used is in my entire history with Python (That might be because I am still having trouble wrapping my head around OOP). Just use the regular equality operator ==.

Null Spark
  • 389
  • 1
  • 14
  • Somebody gave me the impression that `is` is more Pythonic. I guess they were wrong. I would keep it in mind now onwards. Thanks :) – سیف خان Apr 23 '16 at 23:18