Python: 扩大any()函数中迭代器变量的作用域
Python: Expanding the scope of the iterator variable in the any() function
我写了一些结构上等效的真实世界代码,我预计 firstAdjective
的结果将是 quick
。但结果显示 word
超出范围。有什么巧妙的解决方案可以克服这个问题,但仍保留我想做的 'linguistic' 风格?
>>> text = 'the quick brown fox jumps over the lazy dog'
>>> adjectives = ['slow', 'quick', 'brown', 'lazy']
>>> if any(word in text for word in adjectives):
... firstAdjective = word
...
Traceback (most recent call last):
File "<interactive input>", line 2, in <module>
NameError: name 'word' is not defined
您可以在 生成器表达式上使用 next
:
firstAdjective = next((word for word in adjectives if word in text), None)
if firstAdjective:
...
当找不到单词时返回默认值 None
(信用@Bakuriu)
试用:
>>> firstadjective = next((word for word in adjectives if word in text), None)
>>> firstadjective
'quick'
想要
for word in filter(lambda x: x in adjectives, text.split()):
print word
工作?
您的示例不起作用,因为 word
变量仅在条件评估期间存在。一旦确定条件是真还是假,变量就会超出范围并且不再存在。
即使先声明它也无济于事,因为它不会影响现有变量:
text = 'the quick brown fox jumps over the lazy dog'
adjectives = ['slow', 'quick', 'brown', 'lazy']
word = None
if any(word in text for word in adjectives):
print(word)
None
因此,您必须使用 next
函数以不同的方式进行操作:
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
注意,这里可能 word
是一个误导性的变量名,因为它不一定必须匹配整个单词。即
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
所以最好先将文本拆分成单词:
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)
但请注意,如果我们更改形容词顺序:
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)
我们得到:
brown
这不是文中的第一个形容词。
因此,我们需要检查的是单词在文本中的顺序,而不是形容词在列表中的顺序。
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)
>>> 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
>>>
我写了一些结构上等效的真实世界代码,我预计 firstAdjective
的结果将是 quick
。但结果显示 word
超出范围。有什么巧妙的解决方案可以克服这个问题,但仍保留我想做的 'linguistic' 风格?
>>> text = 'the quick brown fox jumps over the lazy dog'
>>> adjectives = ['slow', 'quick', 'brown', 'lazy']
>>> if any(word in text for word in adjectives):
... firstAdjective = word
...
Traceback (most recent call last):
File "<interactive input>", line 2, in <module>
NameError: name 'word' is not defined
您可以在 生成器表达式上使用 next
:
firstAdjective = next((word for word in adjectives if word in text), None)
if firstAdjective:
...
当找不到单词时返回默认值 None
(信用@Bakuriu)
试用:
>>> firstadjective = next((word for word in adjectives if word in text), None)
>>> firstadjective
'quick'
想要
for word in filter(lambda x: x in adjectives, text.split()):
print word
工作?
您的示例不起作用,因为 word
变量仅在条件评估期间存在。一旦确定条件是真还是假,变量就会超出范围并且不再存在。
即使先声明它也无济于事,因为它不会影响现有变量:
text = 'the quick brown fox jumps over the lazy dog'
adjectives = ['slow', 'quick', 'brown', 'lazy']
word = None
if any(word in text for word in adjectives):
print(word)
None
因此,您必须使用 next
函数以不同的方式进行操作:
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
注意,这里可能 word
是一个误导性的变量名,因为它不一定必须匹配整个单词。即
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
所以最好先将文本拆分成单词:
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)
但请注意,如果我们更改形容词顺序:
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)
我们得到:
brown
这不是文中的第一个形容词。
因此,我们需要检查的是单词在文本中的顺序,而不是形容词在列表中的顺序。
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)
>>> 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
>>>