繁体   English   中英

基于内部列表的元素的比较从列表列表中删除重复项

[英]Removing duplicates from a list of lists based on a comparison of an element of the inner lists

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

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

[[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实现这一目标吗?

您可以使用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参数定义了一个可调用的函数,它与Python的排序函数的键参数一样,从每个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等。

如果我得到正确的解决方案,解决方案可能是这样的:

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]]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM