【问题标题】:How to quickly generating a list of all pairs from a large set of numbers?如何从大量数字中快速生成所有对的列表?
【发布时间】:2017-12-17 18:00:45
【问题描述】:

我创建了一个数字从 0 到 131072 的列表:

x = [i for i in range(131072)] 

然后是所有对,除了相同数字的对:

pairs = []
append_pairs = pairs.append
for i in range(len(x)):
    for j in range(len(x)):
        if x[i]!=x[j]:
           x2 = [x[i], x[j]] 
           append_pairs(x2)

给出:

pairs = [[0, 1], [0, 2], [0, 3], ... [131071, 131070]]

但是在这种语法中,它需要很长时间。能不能快一点?

【问题讨论】:

  • 从一组元素生成所有对的下限时间复杂度为 O(n^2),其中 n 是元素的数量。这个下限意味着我们永远不会比 O(n^2) 更快。

标签: python python-3.x list combinations


【解决方案1】:

您可以使用itertools.combinations,但这可能也需要一点时间:

import itertools as it

n = 131072
pairs = it.combinations(range(n), 2)

请注意,上面的代码不会为您提供所有对的列表,而是对对的生成器:

>>> pairs
<itertools.combinations at 0x7fb939a72a48>

您可以使用获取列表

pairs = list(it.combinations(range(n), 2)

使用 numpy 可能更快:

import numpy as np

pairs = np.transpose(np.triu_indices(n, 1))

但是,您想要生成的配对数量巨大,并且您无法将这些数字存储在内存中(除非您有一台非常强大的机器)。特别是,您会得到n * (n - 1) / 2 对。如果您将数字存储为 8 字节整数,那么您将看到不到 70 GB 的内存。

对于n = 5000

  • Itertools:每个循环 818 毫秒 ± 15.8 毫秒(7 次运行的平均值 ± 标准偏差,每次 1 个循环)
  • Numpy:每个循环 254 毫秒 ± 30.8 毫秒(平均值 ± 标准偏差,7 次运行,每次 1 个循环)
  • 原始方法:每个循环 3.72 秒 ± 72.6 毫秒(平均值 ± 标准偏差,7 次运行,每次 1 次循环)

注意:因为有更多可用的内置代码,所以我生成了不同的对。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-23
    • 2020-10-13
    相关资源
    最近更新 更多