如何从列表中删除几乎重复的整数?

时间:2014-04-17 18:17:04

标签: python list sorting

我正在使用Python解析一些PDF。这些PDF在视觉上组织成行和列。 pdftohtml脚本将这些PDF转换为XML格式,其中包含没有任何层次结构的松散<text>标记。然后,我的代码需要将这些<text>标记排序回行。

由于每个<text>标记都有“top”或“left”坐标等属性,因此我编写了代码,将具有相同“top”坐标的<text>项追加到列表中。这个清单实际上是一行。

我的代码首先遍历页面,找到所有唯一的“顶部”值,然后将它们附加到顶部列表。然后它迭代这个tops列表。对于每个唯一的最高值,它会搜索具有“最高”值的所有项目,并将它们添加到行列表中。

for side in page:
    tops = list( set( [ d['top'] for d in side ] ) )
    tops.sort()
    for top in tops:
        row = []
        for blob in side:
            if int(blob['top']) == int(top):
                row.append(blob)
        rows.append(row)

此代码适用于我正在解析的大多数PDF。但是有些情况下,同一行中的项目略微不同的顶部值,关闭一两个。

我正在尝试使我的代码变得有点模糊。

底部的比较似乎很容易解决。像这样:

        for blob in side:
            rangeLower = int(top) - 2
            rangeUpper = int(top) + 2
            thisTop = int(blob['top'])
            if rangeLower <= thisTop <= rangeUpper :
                row.append(blob)

但我首先创建的唯一顶级值列表是个问题。我使用的代码是

    tops = list( set( [ d['top'] for d in side ] ) )

在这些边缘情况下,我最终得到了一个列表:

[925, 946, 966, 995, 996, 1015, 1035]

我如何调整该代码以避免列表中包含“995”和“996”?我想确保当整数在1或2之间时,我只得到一个值。

2 个答案:

答案 0 :(得分:3)

  • 对列表进行排序以使接近的值彼此相邻
  • 使用reduce根据以前的值过滤值

代码:

>>> tops = [925, 946, 966, 995, 996, 1015, 1035]
>>> threshold = 2
>>> reduce(lambda x, y: x + [y] if len(x) == 0 or y > x[-1] + threshold else x, sorted(tops), [])
[925, 946, 966, 995, 1015, 1035]

有几个连续的值:

>>> tops = range(10)
>>> reduce(lambda x, y: x + [y] if len(x) == 0 or y > x[-1] + threshold else x, sorted(tops), [])
[0, 3, 6, 9]

修改

阅读减少可能有点麻烦,所以这里有一个更简单的方法:

res = []
for item in sorted(tops):
    if len(res) == 0 or item > res[-1] + threshold:
        res.append(item)

答案 1 :(得分:0)

@ njzk2的答案也有效,但这个功能实际上显示了正在发生的事情并且更容易理解:

>>> def sort(list):
...     list.sort() #sorts in ascending order
...     x = range(0, len(list), 1) #gets range
...     x.reverse() #reverses
...     for k in x:
...             if list[k]-1 == list[k-1]: #if the list value -1 is equal to the next,
...                     del(list[k-1])     #remove it
...     return list #return
... 
>>> tops = [925, 946, 966, 995, 996, 1015, 1035]
>>> sort(tops)
[925, 946, 966, 996, 1015, 1035]
>>>