首页 > 解决方案 > 多行v单行for循环不同的结果

问题描述

这是一个关于 Kaggle/Python/字符串和字典的练习。我无法解决它,所以我偷看了解决方案并尝试以我会这样做的方式编写它(即不一定像我理解的那样复杂但以我理解的方式)。我使用 Python 导师来可视化代码背后发生的事情并理解大多数事情,但 for 循环让我很着迷。

normalised = (token.strip(",.").lower() for token in tokens)这有效并给了我index [0]

但如果我重写为:

for token in tokens:
    normalised = token.strip(",.").lower()

它不起作用;它给了我index [0][2](大概是因为赌场在 Casinoville)。有人可以编写多行等效项:for token in tokens:...吗?


代码如下以获得更多上下文。

def word_search(doc_list, keyword):
Takes a list of documents (each document is a string) and a keyword. 
Returns list of the index values into the original list for all documents 
containing the keyword.

Example:
doc_list = ["The Learn Python Challenge Casino.", "They bought a car", "Casinoville"]
>>> word_search(doc_list, 'casino')
>>> [0]
"""

indices = []
counter = 0
for doc in doc_list:
    tokens = doc.split()
    **normalised = (token.strip(",.").lower() for token in tokens)**
    if keyword.lower() in normalised:
            indices.append(counter)
    counter += 1
return indices

#Test - output should be [0]
doc_list = ["The Learn Python Challenge Casino.", "They bought a car", "Casinoville"]
keyword = 'Casino'
print(word_search(doc_list,keyword))

标签: pythonfor-loopkaggle

解决方案


normalised = (token.strip(",.").lower() for token in tokens) 返回一个元组生成器。让我们探索一下:

>>> a = [1,2,3]
>>> [x**2 for x in a]
[1, 4, 9]

这是一个列表理解。多行等效项是:

>>> a = [1,2,3]
>>> b = []
>>> for x in a:
...     b.append(x**2)
...
>>> print(b)
[1, 4, 9]

使用括号而不是方括号不会返回一个元组(正如我之前所做的那样,有人可能会天真地怀疑),而是一个生成器:

>>> a = [1,2,3]
>>> (x**2 for x in a)
<generator object <genexpr> at 0x0000024BD6E33B48>

我们可以遍历这个对象next

>>> a = [1,2,3]
>>> b = (x**2 for x in a)
>>> next(b)
1
>>> next(b)
4
>>> next(b)
9
>>> next(b)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

这可以写成这样的多行表达式:

>>> a = [1,2,3]
>>> def my_iterator(x):
...     for k in x:
...             yield k**2
...
>>> b = my_iterator(a)
>>> next(b)
1
>>> next(b)
4
>>> next(b)
9
>>> next(b)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

在原始示例中,使用了in比较。这适用于列表和生成器,但对于生成器它只工作一次:

>>> a = [1,2,3]
>>> b = [x**2 for x in a]
>>> 9 in b
True
>>> 5 in b
False
>>> b = (x**2 for x in a)
>>> 9 in b
True
>>> 9 in b
False

以下是对生成器重置问题的讨论:Resetting generator object in Python

我希望澄清列表推导、生成器和多行循环之间的区别。


推荐阅读