Jarad
Jarad

Reputation: 18933

Why doesn't this Python "any" function return True?

I don't understand why any() is not working the way I expect it to. Below, I want to say, if any of the cities in the cities list are in the phrase.split(), return True. But why does it return false when phrase.split() is ['replacement', 'windows', 'in', 'seattle', 'wa'] and 'seattle' is clearly in the phrase.split() list?

>>> cities = ['seattle', 'san antonio', 'denver']
>>> phrase = 'replacement windows in seattle wa'
>>> any(cities) in phrase.split()
False
>>> 'seattle' in phrase.split()
True

Upvotes: 1

Views: 1295

Answers (5)

Jon Clements
Jon Clements

Reputation: 142176

Because in any(cities) will return True for a non-empty list, or False for an empty list - that value is never contained in your membership test. Also note that splitting by space is going to separate san antonio into two words, so using this approach you won't be able to match it. An alternative is instead to use a regular expression:

import re

cities = ['seattle', 'san antonio', 'denver']
phrase = 'replacement windows in seattle wa'

has_city = re.compile('|'.join(sorted(cities, key=len, reverse=True))).search
if has_city(phrase):
    # do whatever

This is very similar to if any(city in phrase for city in cities) (it will find san antonio) but requires multiple parses over phrase instead of the regex doing it just once.

You might also wish to consider re.escaping the strings and applying word boundaries depending on the exact criteria for matching.

Upvotes: 3

lqhcpsgbl
lqhcpsgbl

Reputation: 3782

Becuse any(cities) return True, and True is not in the list:

>>> cities = ['seattle', 'san antonio', 'denver']
>>> phrase = 'replacement windows in seattle wa'
>>> any(cities)
True
>>> True in phrase.split()
False
>>> any(cities) in phrase.split()
False

You can use this way to see if any city in the list:

>>> [i for i in cities if i in phrase.split()]
['seattle']
>>> any(i for i in phrase.split() if i in cities)
True

Upvotes: 5

sujoy
sujoy

Reputation: 135

Here goes another way to do it correctly,

any(word in cities for word in phrase.split())

Or,

any(True for word in phrase.split() if word in cities)

Upvotes: 0

radsine
radsine

Reputation: 66

Try this statement

any(word in phrase.split() for word in cities)

Your original statement is not really testing every word in "cities" to every word in "phrase.split()."

Upvotes: 1

Takahiro
Takahiro

Reputation: 1262

any(x for x in cities if x in phrase.split())

Upvotes: 0

Related Questions