vbiqvitovs
vbiqvitovs

Reputation: 1723

If substring in string, when substring has multiple values

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

Answers (5)

Flamingo
Flamingo

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

ZJS
ZJS

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

timgeb
timgeb

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

g.d.d.c
g.d.d.c

Reputation: 47988

You probably want any:

if any(substr in string for substr in substrs):
  # At least one match 

Upvotes: 0

kindall
kindall

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 ors 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

Related Questions