我正在尝试使用 NLTK 的文本拼接代码 ( https://github.com/nltk/nltk/blob/develop/nltk/tokenize/texttiling.py )。
它是一种代码,可根据其内容将文档输入分成几个图 block 。我注意到通过将整个文本作为一个拼贴返回,拼贴对于某些文档根本不起作用,并且发现这部分代码工作异常。
depth_tuples = sorted(zip(depth_scores, range(len(depth_scores))))
depth_tuples.reverse()
hp = filter(lambda x:x[0]>cutoff, depth_tuples)
for dt in hp:
boundaries[dt[1]] = 1
for dt2 in hp: #undo if there is a boundary close already
if dt[1] != dt2[1] and abs(dt2[1]-dt[1]) < 4 \
and boundaries[dt2[1]] == 1:
boundaries[dt[1]] = 0
return boundaries
Depth_tuple 是一个包含元组列表 [(score, index)] 的列表,hp 是一个筛选结果,其分数大于某个截止值。
使用嵌套循环,它为 hp 的每个条目分别迭代 hp 两次。换句话说,对于 hp 的每个条目,它应该检查 hp 的所有条目。但是我注意到第二个循环(对于 hp 中的 dt2)在第一次迭代后没有执行。这就像 dt2 指针到达第一个 dt 的 hp 末尾,并且没有为新的迭代初始化。
为了给你一个这种现象的简单例子, 说 x = [(0.6,3),(0.2,1),(0.5,2),(0.4,3)]
如果截止值为 0.3,则 hp 包含 [(0.6,3), (0.5, 2), (0.4, 3)]
所以循环应该是这样的
当 x = (0.6, 3) 时,第二个循环检查 [(0.6,3), (0.5, 2), (0.4, 3)]
当 x = (0.5, 2) 时,第二个循环再次检查 [(0.6,3), (0.5, 2), (0.4, 3)]
但它仅在 x=(0.6, 3) 时执行此操作,对于 x 的其余部分,第二个循环不会运行。
我最初怀疑迭代器在第二个循环已经到达了hp的末尾,但它不能解释第一个循环的hp中的迭代器如何仍然可以......
您能解释一下为什么会这样吗?谢谢!
最佳答案
您使用的是 Python 3,而该食谱是为 Python 2 编写的。在 Python 2 中, filter
返回一个list
,显然可以用for
迭代多次(hp中的for dt2
>).
但是在 Python 3 中,hp
将是 a one-pass iterator ;现在,外部 for
将消耗第一个元素,而内部 for
将消耗所有剩余元素;当内循环退出时,外循环找到一个空迭代器并退出。
或者,正如 Python 2 和 3 文档所说,在 Python 2 中,filter(function, iterable)
等同于列表理解
[item for item in iterable if function(item)]
而在Python 3中,它等同于生成器表达式
(item for item in iterable if function(item))
作为最简单的修复,将 filter
返回的迭代器放入 list
中:
hp = list(filter(lambda x: x[0] > cutoff, depth_tuples))
关于Python 3.4 嵌套循环使用 lambda 过滤器工作异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29904084/