0

How to check a string for specific characters? I find the link is very useful. But what's wrong with my codes?

string = "A17_B_C_S.txt"

if ("M.txt" and "17") in string:
    print True
else:
    print False

and the answer always comes out

True
Community
  • 1
  • 1
Shengen
  • 73
  • 5
  • Closely related: [if x or y or z == blah](http://stackoverflow.com/q/15112125) – Martijn Pieters Jul 25 '13 at 12:40
  • Don't use `if some_boolean_test: print True; else: print False` when just `print some_boolean_test` will do. – Martijn Pieters Jul 25 '13 at 12:41
  • 1
    +1 this is a common trap when moving from existing figures of "speech" to own constructs without fully grasping the full implications of each subelement, absolutely legitimate question IMO – Nicolas78 Jul 25 '13 at 12:51

4 Answers4

3

This is because your and evaluates to 17 which is in stringList. The and evaluates to 17 because of short circuiting.

>>> "M.txt" and "17"
'17'

Python evaluates non empty strings to the value True. Hence, M.txt evaluates to True, thus the value of the expression depends on the second value which is returned(17) and is found in the stringList. (Why? When and is performed with a True value, the value of the expression depends on the second value, if it's False, the value of the expression is False, else, it's True.)

You need to change your expression to

if "M.txt" in stringList and "17" in stringList:
    #...

Or use the builtin all()

if all(elem in stringList for elem in ["M.txt", "17"]):
    #...
Sukrit Kalra
  • 33,167
  • 7
  • 69
  • 71
2
stringList = "A17_B_C_S.txt"

if "M.txt" in stringList and "17" in stringList:
    print True
else:
    print False

>>> 
True

('M.txt' and '17') returns '17'. So you are just testing '17' in stringList.

>>> ('M.txt' and '17')
'17'
>>> 
zhangyangyu
  • 8,520
  • 2
  • 33
  • 43
2

That's because

("M.txt" and "17") in string

doesn't mean what it may sound like. In python, it means:

test if a value, you'll get when performing boolean and between "M.txt" and "17", is found inside a 'string'

and in your code performs not only the and operator, but also returns the final term, which is "17". Therefore ("M.txt" and "17") will return "17", and so it will in fact only test if "17" is in a string

If what you actually wanted was:

test if there is "M.txt" in string and also "17" in string

you have to write:

if "M.txt" in string and "17" in string:
Jan Spurny
  • 5,219
  • 1
  • 33
  • 47
1

("M.txt" and "17") returns "17" because it evaluates to (True and True) (bool("M.txt") == True). Thus, the second one is chosen.

Then you're trying to say if "17" in string.

You have to individually compare the items:

if "M.txt" in stringList and "17" in stringList:

Or even:

if all(i in stringList for i in ("M.txt", "17")):
TerryA
  • 58,805
  • 11
  • 114
  • 143