89
if var is 'stringone' or 'stringtwo':
    dosomething()

This does not work! I have a variable and I need it to do something when it is either of the values, but it will not enter the if statement. In Java if (var == "stringone" || "stringtwo") works. How do I write this in Python?

ivanleoncz
  • 9,070
  • 7
  • 57
  • 49
Rahul Sharma
  • 1,117
  • 3
  • 10
  • 12

5 Answers5

194

This does not do what you expect:

if var is 'stringone' or 'stringtwo':
    dosomething()

It is the same as:

if (var is 'stringone') or 'stringtwo':
    dosomething()

Which is always true, since 'stringtwo' is considered a "true" value.

There are two alternatives:

if var in ('stringone', 'stringtwo'):
    dosomething()

Or you can write separate equality tests,

if var == 'stringone' or var == 'stringtwo':
    dosomething()

Don't use is, because is compares object identity. You might get away with it sometimes because Python interns a lot of strings, just like you might get away with it in Java because Java interns a lot of strings. But don't use is unless you really want object identity.

>>> 'a' + 'b' == 'ab'
True
>>> 'a' + 'b' is 'abc'[:2]
False # but could be True
>>> 'a' + 'b' is 'ab'
True  # but could be False
Messa
  • 24,321
  • 6
  • 68
  • 92
Dietrich Epp
  • 205,541
  • 37
  • 345
  • 415
33
if var == 'stringone' or var == 'stringtwo':
    do_something()

or more pythonic,

if var in ['string one', 'string two']:
    do_something()
iMom0
  • 12,493
  • 3
  • 49
  • 61
inspectorG4dget
  • 110,290
  • 27
  • 149
  • 241
  • @DSM missing colon, too. – iMom0 Oct 08 '12 at 01:31
  • 1
    Why is the second one considered more pythonic? – Rahul Sharma Oct 08 '12 at 01:43
  • 3
    @RahulSharma http://www.jeffknupp.com/blog/2012/10/04/writing-idiomatic-python/ Avoid repeating variable name in compound if Statement – iMom0 Oct 08 '12 at 07:38
  • 7
    better yet, since you don't need it to be mutable and don't care what order they are checked in, use a set: `if var in {'string one', 'string two'}:` It's faster, too. – endolith Jul 31 '15 at 01:03
  • @endolith This is intuitive but nonetheless fascinating to me. I've never considered this approach for more pythonic compound if-statements. For small sets, the difference is negligible, so perhaps the point is moot, but it does become significant: https://repl.it/repls/UniformLoneAiredaleterrier – aJetHorn Jan 25 '18 at 16:18
  • 3
    @aJetHorn Actually I think tuples are faster than sets – endolith Jan 25 '18 at 17:02
7
if var == 'stringone' or var == 'stringtwo':
    dosomething()

'is' is used to check if the two references are referred to a same object. It compare the memory address. Apparently, 'stringone' and 'var' are different objects, they just contains the same string, but they are two different instances of the class 'str'. So they of course has two different memory addresses, and the 'is' will return False.

Lingfeng Xiong
  • 1,131
  • 2
  • 9
  • 25
4

Two separate checks. Also, use == rather than is to check for equality rather than identity.

 if var=='stringone' or var=='stringtwo':
     dosomething()
Andrew Jaffe
  • 26,554
  • 4
  • 50
  • 59
0
for a in soup("p",{'id':'pagination'})[0]("a",{'href': True}):
        if createunicode(a.text) in ['<','<']:
            links.append(a.attrMap['href'])
        else:
            continue

It works for me.

Yaseer Arafat
  • 81
  • 1
  • 4