2

我有一个包含 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 的那些。所以 newlist 将是:

new_list = [[2, 3, 4, 5, 6, 7], [2, 3, 4, 26, 33, 40]]

目前我正在使用设置交叉点,但运行大约需要 30 秒

4

3 回答 3

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]
于 2012-06-19T08:21:45.360 回答
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]]
于 2012-06-19T08:22:33.550 回答
0

我认为“快速”解决方案应该取决于您的问题的规范。例如,如果您的参考列表与 [1, 3, 4, 10, 23, 46] 一样短,通过对每个列表进行排序,我们可以立即看到所有以 num 大于 10 开头的列表,例如 [ 11, x, x, ...] 与参考的共同元素不会超过 3 个。这已经可以节省很多比较。

于 2012-06-19T13:14:54.427 回答