Python中合并和删除重复ID的最快方法

时间:2016-05-22 18:26:05

标签: python django python-3.x numpy

我有两个不同的查询集,我需要合并在一起,然后删除任何重复的ID。有超过一百万的记录。

list_a = Wharehouse.orders.all().values_list('id', flat=True)
list_b = Shops.orders.all().values_list('id', flat=True)

有这种快速的pythonic方法吗?

我可以考虑使用列表理解并循环每个值。但是,这可以在numpy更好/更快或可能是一组?输出只需要是一个id列表。

我使用Python 3.4和Django安装了numpy 1.11.0 pip。

4 个答案:

答案 0 :(得分:3)

假设list_alist_b是整数列表,您可以使用np.union1d(list_a, list_b)。使用:

import numpy as np
N = 10**6
list_a = np.random.randint(2*10**6, size=N).tolist()
list_b = np.random.randint(2*10**6, size=N).tolist()

这是一个基准测试,建议np.union1d在应用于包含大约一百万个元素的列表时可能会更快:

In [32]: %timeit np.union1d(list_a, list_b)
1 loop, best of 3: 296 ms per loop

In [40]: %timeit set(list_a + list_b)
1 loop, best of 3: 308 ms per loop

In [31]: %timeit set(list_a).union(list_b)
1 loop, best of 3: 338 ms per loop

In [33]: %timeit list(set(list_a + list_b))
1 loop, best of 3: 382 ms per loop

注意,当然,np.union1d返回一个NumPy数组,而setlist返回同名类型的Python对象,因此基准在某种程度上是一个苹果到 - 橙色比较。

答案 1 :(得分:1)

尝试将其投射到set以删除重复项。然后,您可以将其返回到列表中。要连接列表,请使用+运算符。它会做到这一点(至少在普通列表中)

merged = list(set(list_a + list_b))

答案 2 :(得分:1)

一种方法是使用Sets.

我们创建了2套set_aset_bset_a包含Wharehouse个对象的所有ID。 set_b包含所有Shops个ID。现在结合所有唯一ID,我们对集合使用union操作。 final_set包含所有所需的唯一ID。

set_a = set(Wharehouse.orders.all().values_list('id', flat=True))
set_b = set(Shops.orders.all().values_list('id', flat=True))

final_set = set_a.union(set_b) # contains all unique ids combined 

答案 3 :(得分:0)

shops_query=Shops.orders.all().values_list('id', flat=True)
result = Wharehouse.orders.all().exclude(id__in=shops_query).values_list('id', flat=True)

让DB完成工作。