根据内部列表元素

时间:2015-12-17 12:15:49

标签: python

我有一个很大的列表列表,需要根据特定条件删除重复的元素:

  1. 唯一性由列表的第一个元素决定。
  2. 通过比较重复列表的第二个元素的值来确定删除重复项,即保持列表具有最低的第二个元素。
  3. [[1, 4, 5], [1, 3, 4], [1, 2, 3]]

    以上所有列表都被认为是重复的,因为它们的第一个元素是相同的。需要保留第三个列表,因为它的第二个元素是最小的。请注意,实际的列表列表有超过400万个元素,是双重排序的,需要保留排序。

    列表首先根据内部列表的第二个元素以反向(降序)顺序排序,然后是基于第一个元素的正常(升序)顺序:

    sorted(sorted(the_list, key=itemgetter(1), reverse=True), key=itemgetter(0))
    

    实际排序中三个重复列表的示例:

    [...
    [33554432, 50331647, 1695008306],
    [33554432, 34603007, 1904606324],
    [33554432, 33554687, 2208089473],
    ...]
    

    目标是准备二等分搜索列表。有人能让我了解如何使用Python实现这一目标吗?

2 个答案:

答案 0 :(得分:2)

您可以使用dict对元素进行分组,始终使用较小的第二个元素保留子列表:

l = [[1, 2, 3], [1, 3, 4], [1, 4, 5], [2, 4, 3], [2, 5, 6], [2, 1, 3]]
d = {}
for sub in l:
    k = sub[0]
    if k not in d or sub[1] < d[k][1]:
        d[k] = sub

此外,您可以将两个键传递给已排序,您不需要调用两次排序:

In [3]:  l = [[1,4,6,2],[2,2,4,6],[1,2,4,5]]
In [4]: sorted(l,key=lambda x: (-x[1],x[0]))
Out[4]: [[1, 4, 6, 2], [1, 2, 4, 5], [2, 2, 4, 6]]

如果您希望按照维护dict中的顺序,则需要保留订单。

from collections import OrderedDict

l = [[1, 2, 3], [1, 3, 4], [1, 4, 5], [2, 4, 3], [2, 5, 6], [2, 1, 3]]
d = OrderedDict()
for sub in l:
    k = sub[0]
    if k not in d or sub[1] < d[k][1]:
        d[sub[0]] = sub

但不确定这样做是否合适,因为您将丢失任何订单后对数据进行排序。

您可能会觉得非常有用的是sortedcontainers.sorteddict

  

SortedDict提供与dict相同的方法。此外,SortedDict有效地按排序顺序维护其键。因此,keys方法将按排序顺序返回键,popitem方法将删除具有最高键的项目等。

     

可选的key参数定义了一个callable,它与Python的sort函数的key参数一样,从每个dict键中提取一个比较键。如果未指定任何功能,则默认直接比较dict键。键参数必须作为位置参数提供,并且必须在所有其他参数之前。

from sortedcontainers import SortedDict

l = [[1, 2, 3], [1, 3, 4], [1, 4, 5], [2, 4, 3], [2, 5, 6], [2, 1, 3]]
d = SortedDict()
for sub in l:
    k = sub[0]
    if k not in d or sub[1] < d[k][1]:
        d[k] = sub


print(list(d.values()))

它包含您想要的所有方法bisectbisect_left等等。

答案 1 :(得分:1)

如果我说得对,解决方案可能是这样的:

mylist = [[1, 2, 3], [1, 3, 4], [1, 4, 5], [7, 3, 6], [7, 1, 8]]

ordering = []
newdata = {}

for a, b, c in mylist:
    if a in newdata:
        if b < newdata[a][1]:
            newdata[a] = [a, b, c]
    else:
        newdata[a] = [a, b, c]
        ordering.append(a)

newlist = [newdata[v] for v in ordering]

因此,在newlist中,我们会收到[[1, 2, 3], [7, 1, 8]]的简化列表。