我有两个不同的查询集,我需要合并在一起,然后删除任何重复的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。
答案 0 :(得分:3)
假设list_a
和list_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数组,而set
和list
返回同名类型的Python对象,因此基准在某种程度上是一个苹果到 - 橙色比较。
答案 1 :(得分:1)
尝试将其投射到set
以删除重复项。然后,您可以将其返回到列表中。要连接列表,请使用+
运算符。它会做到这一点(至少在普通列表中)
merged = list(set(list_a + list_b))
答案 2 :(得分:1)
一种方法是使用Sets
.
我们创建了2套set_a
和set_b
。 set_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完成工作。