【问题标题】:Python comparing list of listsPython比较列表列表
【发布时间】:2012-06-19 08:15:36
【问题描述】:

我有一个包含 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 秒

【问题讨论】:

  • 我们也可以看看你的代码,以及一个更清晰、明确的问题吗?

标签: python performance list compare


【解决方案1】:
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]

【讨论】:

    【解决方案2】:
    >>> 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]]
    

    【讨论】:

    • 目前,使用交集是最快的。预先将 biglist 项转换为集合使其更快,但给 MemoryError 带来了 10**7 项。所以现在必须这样做。
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-19
      • 2021-10-20
      • 2018-03-19
      • 1970-01-01
      • 1970-01-01
      • 2017-03-12
      相关资源
      最近更新 更多