How to check if a variable matches any item in list using the any function?
any(a)
means "is any item in a
truthy"? And the result is True
because every item in a
is truthy. (Any non-zero-length string is truthy, and every item in a
is a non-zero-length string.)
And then you are comparing that result, True
, to, say, "A"
. True
is not equal to "A"
so the result of that comparison is, of course, False
.
What you probably want to do is something like:
"A" in a # True
If you must use any()
for some reason, try:
any(item == "A" for item in a)
This approach has the advantage of being able to do imprecise comparisons easily (in
will only do exact comparisons). For example:
any(item.lower() == "a" for item in a) # case-insensitive
any("a" in item.lower() for item in a) # substring match
any(item.lower().startswith("a") for item in a)
The problem is that any()
returns True
if any one of the elements in the iterable is True
, so your code keeps looping as long as the answer isn't equal to all the strings in months_list
—which is probably the opposite of what you want to happen. Here's a way to use it that stops or breaks-out of the loop if the answer matches any of the strings:
months_list = ["January", "February", "March", "April", "May", "June", "July"]
while True:
answer = raw_input("Month? ")
if any(item.lower() == answer.lower() for item in months_list):
break
print("Sorry, didn't recognize your answer, try again")
As others have pointed out, while it would simpler to use Python's in
operator, that way still results in a linear search, O(n), being performed…so an even better (faster) approach would be to use a set
of lower-cased month_names
, which would utilize a hash table based look-up, O(1), instead of a linear search:
months = set(month.lower() for month in ("January", "February", "March", "April",
"May", "June", "July"))
while True:
answer = raw_input("Month? ")
if answer.lower() in months:
break
print("Sorry, didn't recognize your answer, try again")
Further refinement
Depending on the nature of strings involved and why you're comparing them, it might be better to use the string casefold()
method instead of lower()
to do caseless string comparisons.
To check membership, use in
:
>>> a = ['a','b','c','d']
>>> 'a' in a
True
>>> 'z' in a
False