pan*_*mer 2 python lambda loops python-3.x
我正在尝试使用NLTK的文本代码(https://github.com/nltk/nltk/blob/develop/nltk/tokenize/texttiling.py).
它是一个代码,根据文档内容将文档输入分成几个图块.我注意到,通过将整个文本作为一个瓦片返回,平铺对于某些文档根本不起作用,并且发现这部分代码工作很奇怪.
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
Run Code Online (Sandbox Code Playgroud)
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返回a list,显然可以使用for(内部for dt2 in hp)多次迭代.
但是在Python 3中,hp将是一个通过迭代器 ; 现在,外部for将消耗第一个元素,而内部for将消耗所有剩余元素; 当内循环退出时,外循环找到一个空迭代器并退出.
或者,正如Python 2和3文档所述,在Python 2 filter(function, iterable)中等同于列表理解
[item for item in iterable if function(item)]
Run Code Online (Sandbox Code Playgroud)
在Python 3中,它等同于生成器表达式
(item for item in iterable if function(item))
Run Code Online (Sandbox Code Playgroud)
作为最简单的修复,将迭代器返回filter到list:
hp = list(filter(lambda x: x[0] > cutoff, depth_tuples))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
960 次 |
| 最近记录: |