1

A simple question usually has a simple answer but I am struggling to find it. Can someone please explain why the following isn't matching?

string = 'HTTP/NONE'
if string is 'HTTP/NONE': print 'match'
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
evillen
  • 103
  • 2
  • 8
  • 1
    possible duplicate of [Python '==' vs 'is' comparing strings, 'is' fails sometimes, why?](http://stackoverflow.com/questions/1504717/python-vs-is-comparing-strings-is-fails-sometimes-why) – Martijn Pieters Apr 11 '13 at 09:52

5 Answers5

3

Use::

string = 'HTTP/NONE'
if string == 'HTTP/NONE':
    print 'Match!'
else:
    print 'No Match!'

Works for me. Apparently, strings like ==

  • 3
    You misunderstand what `is` *means*. `int`s 'like' `==` too.. Testing for equality is a very different operation from testing for identity. Two 1 dollar notes have the same *value*, but they are still two separate pieces of paper. They are equal, but have separate identities. – Martijn Pieters Apr 11 '13 at 09:54
  • @jamylak: sorry 'bout the semicolons, come from a C background XD – Binayaka Chakraborty Apr 12 '13 at 06:27
  • @BinayakaChakraborty You still aren't allowed to use them! – jamylak Apr 12 '13 at 06:29
2

Use == instead. Also be wary not to name a variable the same name as a python module.

>>> mystr = 'HTTP/NONE'
>>> mystr is 'HTTP/NONE'
False
>>> mystr == 'HTTP/NONE'
True

The is operator tests for identity - and only returns True for objects that have the same id. == only checks if the two objects have the same value, which is what you want here. If we check the ids of mystr and 'HTTP/NONE', we can see they are different.

>>> id(mystr)
64342000
>>> id('HTTP/NONE')
64341360
Volatility
  • 31,232
  • 10
  • 80
  • 89
2

is tests for identity. From the Python 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.

When dealing with comparing values you're better of using ==. Example ipython session:

In [1]: s = 'A/B'

In [2]: s == 'A/B'
Out[2]: True

In [3]: s is 'A/B'
Out[3]: False

In [4]: b = 'A/B'

In [5]: s is b
Out[5]: False

In [6]: b == s
Out[6]: True

Given that the identity operator checks the id of the objects compared, its result has quirks because Python caches int, float, small strings. This is visible by calling the id() function:

In [28]: s1, s2 = 'Joe', 'Joe'

In [29]: id(s1), id(s2)
Out[29]: (21399760, 21399760)

In [30]: s1 is s2
Out[30]: True

As you can see, in this case, even though they were created by different assignment operations, both s1 and s2 are the same object.

Here's a similar case with int objects, related to this explanation from the Python documentation:

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.

I didn't find the explanation for the string type, but I assume the same is going on, and as such is shouldn't be used for value comparison. It might sometimes return False and sometimes True:

In [39]: s = 'Joe'

In [40]: id('Joe')
Out[40]: 21403136

In [41]: id(s)
Out[41]: 21403136

In [42]: s is 'Joe'
Out[42]: True

Good luck!

Community
  • 1
  • 1
Mariano
  • 1,357
  • 3
  • 17
  • 30
1

You are testing for identity, not equality. Use == instead.

You are confusing identity with equality. Two 1 dollar banknotes have the same value, so they are equal when it comes to buying a donut. But they each have a separate identity.

To help performance, sometimes Python uses the same object when you tell Python to store the same literal value. This is called interning, and when that happens, you get a reference to an int or a str value that just happens to be the same object too.

is tests for identity; it is basically implemented as id(a) == id(b), two references are identical if the identity of their values is equal. The are referring to the same object, not just the same value.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
0
string = 'HTTP/NONE'
if string == 'HTTP/NONE': print 'match'

It will work.

Priyesh Solanki
  • 707
  • 4
  • 6