我有一个很大的列表列表,需要根据特定条件删除重复的元素:
[[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实现这一目标吗?
答案 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()))
它包含您想要的所有方法bisect,bisect_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]]
的简化列表。