Skip to content Skip to sidebar Skip to footer

Python: Expanding The Scope Of The Iterator Variable In The Any() Function

I wrote some structurally equivalent real world code, where I anticipated the result for firstAdjective would be quick. But the result shows that word is out of scope. What is a ne

Solution 1:

You can use next on a generator expression:

firstAdjective = next((word for word in adjectives if word in text), None)

if firstAdjective:
    ... 

A default value of None is returned when the word is not found (credit @Bakuriu)

Trial:

>>>firstadjective = next((word for word in adjectives if word in text), None)>>>firstadjective
'quick'

Solution 2:

Would something like

for word infilter(lambda x: x in adjectives, text.split()):
    print word

work?

Solution 3:

Your example does not work because the word variable only exists during the evaluation of the condition. Once it is done finding whether the condition is true or false, the variable goes out of scope and does not exist anymore.

Even declaring it first doesn't help, as it doesn't affect the existing variable:

text = 'the quick brown fox jumps over the lazy dog'
adjectives = ['slow', 'quick', 'brown', 'lazy']
word = Noneifany(word in text for word in adjectives):
    print(word)

None

Therefore, you have to do it differently, using the next function:

text = 'the quick brown fox jumps over the lazy dog'
adjectives = ['slow', 'quick', 'brown', 'lazy']
word = next((word for word in adjectives if word in text), None)
if word:
    print(word)

quick

Note, perhaps word is a misleading variable name here, because it doesn't necessarily have to match a whole word. i.e.

text = 'the quick brown fox jumps over the lazy dog'
adjectives = ['slo', 'uick', 'rown', 'azy']
word = next((word for word in adjectives if word in text), None)
if word:
    print(word)

uick

so it might be best to split the text into words first:

text = 'the quick brown fox jumps over the lazy dog'
adjectives = ['slow', 'quick', 'brown', 'lazy']
word_list = text.split()
word = next((word for word in adjectives if word in word_list), None)
if word:
    print(word)

but note that if we change the adjectives order:

text = 'the quick brown fox jumps over the lazy dog'
adjectives = ['brown', 'quick', 'slow', 'lazy']
word_list = text.split()
word = next((word for word in adjectives if word in word_list), None)
if word:
    print(word)

we get:

brown

which isn't the first adjective in the text.

Therefore, we need to check in the order of the words in the text, not the order of adjectives in the list.

text = 'the quick brown fox jumps over the lazy dog'
adjectives = ['brown', 'quick', 'slow', 'lazy']
word_list = text.split() # NOTE: this"optimization"is no longer necessary now
word = next((word for word in word_list if word in adjectives), None)
if word:
    print(word)

credit to HolyDanna for spotting this

Solution 4:

>>>text = 'the quick brown fox jumps over the lazy dog'>>>>>># 1. Case with no match among the adjectives: Result None as expected>>>adjectives = ['slow', 'crippled']>>>firstAdjective = next((word for word in adjectives if word in text), None)>>>firstAdjective>>>>>># 2. Case with a match to 1st available in adjectives but actually 2nd in the text>>>adjectives = ['slow', 'brown', 'quick', 'lazy']>>>firstAdjective = next((word for word in adjectives if word in text), None)>>>firstAdjective
'brown'
>>># 3. Case with a match to 1st available in the text, which is what is wanted>>>firstAdjective = next((word for word in text.split() if word in adjectives), None)>>>firstAdjective
'quick'
>>># 4. Case where .split() is omitted. NOTE: This does not work. >>># In python 2.7 at least, .split() is required>>>firstAdjective = next((word for word in text if word in adjectives), None)>>>firstAdjective>>>

Post a Comment for "Python: Expanding The Scope Of The Iterator Variable In The Any() Function"