3

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?

Saif Khan
  • 309
  • 1
  • 2
  • 19
  • @gdlmx I must have been looking in wrong places then. Thank you. – Saif Khan Apr 23 '16 at 23:21
  • I never thought to look for difference between `is` and `==`, which is why I never found this post. – Saif Khan 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,377
  • 2
  • 31
  • 50
  • Thank you so much. It never crossed my mind to use `==` instead because I was under the impression that they were both the same. It solved my problem. – Saif Khan Apr 23 '16 at 23:16
  • 1
    You are the best! xD I can't accept your answer for two more minutes. SOs policy. – Saif Khan Apr 23 '16 at 23:24
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
  • 399
  • 2
  • 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 :) – Saif Khan Apr 23 '16 at 23:18