我有一个包含10 ** 7列表的列表,格式为:
big_list = [[1, 2, 3, 4, 5, 6], [2, 3, 4, 5, 6, 7], [2, 3, 4, 26, 33, 40], [10, 23, 33, 45, 46, 47]]
每个列表包含6个唯一的整数。
我需要将每个列表与另一个列表进行比较:
lst = [1, 3, 4, 10, 23, 46]
并返回列表项交集小于3的那些。 所以新名单将是:
new_list = [[2, 3, 4, 5, 6, 7], [2, 3, 4, 26, 33, 40]]
目前我正在使用set intersection,但运行需要大约30秒
答案 0 :(得分:4)
import numpy as np
biglist = [[1, 2, 3, 4, 5, 6], [2, 3, 4, 5, 6, 7], [2, 3, 4, 26, 33, 40], [10, 23, 33, 45, 46, 47]]
oldlist = [1, 3, 4, 10, 23, 46]
b = np.array(biglist)
b[np.array([(b == x).any(axis=1) for x in oldlist]).sum(axis=0) < 3]
返回
array([[ 2, 3, 4, 5, 6, 7],
[ 2, 3, 4, 26, 33, 40]])
numpy数组的创建需要一些时间,但最后一行的速度大约是列表理解的两倍(对于1e6列表)。
编辑:以下行甚至比上面的代码更快,并且需要更少的内存:
b[reduce(np.add, ((b == x).any(axis=1).astype(np.int) for x in oldlist)) < 3]
答案 1 :(得分:1)
>>> big_list = [[1, 2, 3, 4, 5, 6], [2, 3, 4, 5, 6, 7], [2, 3, 4, 26, 33, 40], [10, 23, 33, 45, 46, 47]]
>>> normal = set([1, 3, 4, 10, 23, 46])
>>> [x for x in big_list if len(set(x).intersection(normal)) < 3]
[[2, 3, 4, 5, 6, 7], [2, 3, 4, 26, 33, 40]]
答案 2 :(得分:0)
我认为“快速”解决方案应该取决于您的问题的规范。例如,如果您的参考列表与[1,3,4,10,23,46]一样短,则通过对每个列表进行排序,我们可以立即看到所有以大于10的数字开头的列表,例如[11,x,x,...]与参考不会有超过3个共同元素。这可能已经节省了很多比较。