如何从一大组数字中快速生成所有对的列表?

问题描述 投票:1回答:1

我创建一个包含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]]

但是在这种语法中需要很长时间。可以更快地完成吗?

python python-3.x list combinations
1个回答
2
投票

您可以使用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 ms±15.8 ms(平均值±标准偏差,7次运行,每次循环1次)
  • Numpy:每循环254 ms±30.8 ms(平均值±标准偏差,7次运行,每次循环1次)
  • 原始方法:每循环3.72 s±72.6 ms(平均值±标准偏差,7次运行,每次1次循环)

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