I did some google searching on how to check if a string has any elements of a list in it and I found this bit of code that works:
if any(i in string for i in list):
I know this works, but I don't really know why. Could you share some insight?
I did some google searching on how to check if a string has any elements of a list in it and I found this bit of code that works:
if any(i in string for i in list):
I know this works, but I don't really know why. Could you share some insight?
As the docs for any
say:
Return
True
if any element of the iterable is true. If the iterable is empty, returnFalse
. Equivalent to:
def any(iterable):
for element in iterable:
if element:
return True
return False
So, this is equivalent to:
for element in (i in string for i in list):
if element:
return True
return False
… which is itself effectively equivalent to:
for i in list:
element = i in string
if element:
return True
return False
If you don't understand the last part, first read the tutorial section on list comprehensions, then skip ahead to iterators, generators, and generator expressions.
If you want to really break it down, you can do this:
elements = []
for i in list:
elements.append(i in string)
for element in elements:
if element:
return True
return False
That still isn't exactly the same, because a generator expression builds a generator, not a list, but it should be enough to get you going until you read the tutorial sections.
But meanwhile, the point of having any
and comprehensions and so on is that you can almost read them as plain English:
if any(i in string for i in list): # Python
if any of the i's is in the string, for each i in the list: # pseudo-English
i in string for i in list
This produces an iterable of booleans indicating whether each item in list
is in string
. Then you check whether any item in this iterable of bools is true.
In effect, you're checking whether any of the items in the list are substrings of string
.
What's going on here with:
if any(i in string for i in list):
is best explained by illustrating:
>>> xs = ["Goodbye", "Foo", "Balloon"]
>>> s = "Goodbye World"
>>> [i in s for i in xs]
[True, False, False]
>>> any([i in s for i in xs])
True
If you read the any
documentaiton you'll note:
any(iterable)
Return True if any element of the iterable is true. If the iterable is empty, return False. Equivalent to:
The list comprehension should be more obvious as it constructs a list of i in s
for each element of xs
.
Basically (in English) you are returning any match where each sub-string exists in the search string (haystack).
It's important to note as well that any()
will short circuit and end on the first True
(ish) value it finds. any()
can be implement in pure Python like this:
def any(iterable):
for x in iterable:
if x:
return True
return False