1

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
1

5 Answers 5

5

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
Sign up to request clarification or add additional context in comments.

3 Comments

@zoosuck Thank you, this is very helpful in helping me understand why any() was returning False.
Your any is backwards -- should be any(i in cities for i in phrase.split())
You did not change it. You just change a list comprehension into a generator... Compare any((i for i in phrase.split() if i in cities)) to any(i in cities for i in phrase.split()) in the first form, phrase is being split repeatedly
3

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.

1 Comment

Thank you very much for your well thought-out response. I would have never thought of your suggestion. I also was wondering about how to handle multi-word cities since split() spits on spaces so thanks for helping me on this aspect as well.
1

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()."

Comments

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

Comments

0

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.