我正在尝试使用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

深度元组是一个包含元组列表[(分数,索引])的列表,hp是一个分数大于某个截止值的筛选结果。
使用嵌套循环,它对hp的每个条目分别在hp上迭代两次。换句话说,对于hp的每个条目,它应该检查hp的所有条目。但是我注意到第二个循环(对于hp中的dt2)在第一次迭代之后没有执行。就像第一个dt的dt2指针到达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中如何仍然可以运行。。。
你能解释一下为什么会这样吗?谢谢!

最佳答案

您使用的是Python3,配方是为Python2编写的。在Python 2中,filter返回一个list,显然可以用for(内部for dt2 in hp)重复多次。
但是,在Python 3中,hp将是AA>;现在,外部for将消耗第一个元素,而内部for将消耗所有剩余元素;当内环退出时,外循环找到空迭代器并退出。
或者,正如Python2和3文档所说,在Python2中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 - 使用lambda过滤器的Python 3.4嵌套循环怪异地工作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29904084/

10-13 02:16