Reputation: 1723
I know there is a way to work around it, but I want to understand the underlying logic as to why this doesn't work.
It's a very simple statement, and it only returns as True when the first substring in the "or list" is shown.
for i in list:
if (substring1 or substring2 or substring3) in string:
print(string + " found!")
What am I missing here? I would think the or conditions would equal true if any substring was found in the string. As is, I'm only coming up as true if substring1 is found in string, and no substring2 or substring3.
Upvotes: 3
Views: 996
Reputation: 11
The correct code should be
for i in list:
if (substring1 in i ) or (substring2 in i) or (substring3 in i):
print(i + " found!")
The above code can find substring when they have multiple values.
(substring1 or substring2 or substring3)
This expression will return the first item in brackets that is not null. For example, if subtring1 is not null, it will return the value of substring1. When substring1 is not null,
(substring1 or substring2 or substring3)
equals to
substring1
Upvotes: 1
Reputation: 4051
Its because python uses lazy evaluation... for example...
def error():
raise ArithmeticError
print "nothing" or error()
Will Print "nothing" because it evaluates to True in python code does not check error, which would ordinarily raise an error and stop the script from continuing...
print False or error() #raises error and breaks script
(substring1 or substring2 or substring3) #returns the first true value
Upvotes: 1
Reputation: 78690
>>> string = 'hello'
>>> s1 = 'he'
>>> s2 = 'll'
>>> s3 = 'o'
>>> (s1 or s2 or s3)
'he'
>>> 'he' in string
True
The problem here is that you are first evaluating (s1 or s2 or s3)
which will give you s1
if s1
does not evaluate to false
. In a boolean context, empty strings evaluate to false
:
>>> s1 = ''
>>> (s1 or s2 or s3)
'll'
What you want is s1 in string or s2 in string or s3 in string
, this will return true if at least one of the substrings is in the string.
Upvotes: 3
Reputation: 47988
You probably want any
:
if any(substr in string for substr in substrs):
# At least one match
Upvotes: 0
Reputation: 184191
substring1 or substring2 or substring3
Assuming that substring1
is not the empty string, this expression evaluates to substring1
because substring1
is truthy. This is then checked to see if it's in string
. The other substrings have no effect on the statement.
In other words, the or
s are evaluated before the in
, and the or
evaluates to the first truthy value it finds (this is called short-circuiting). You can't use in
that way to check whether multiple substrings are in a string.
You want:
substring1 in string or substring2 in string or substring3 in string
Or:
substrings = (substring1, substring2, substring3)
if any(s in string for s in substrings):
Upvotes: 5