创建笛卡尔乘积而对内没有重复元素的最快方法

时间:2018-11-28 11:17:29

标签: python list cartesian-product

我有一个图像索引列表,它的长度是60000。我想创建另一个包含随机索引对的列表。这里的约束是产品集的每个元素都应包含不同的索引。换句话说,我不想将索引与其自身配对。

目前,我一直在使用itertools.product循环的for方法。

pairs = []
for pair in itertools.product(indexes, indexes):
    if pair[0]!=pair[1]:
        pairs.append(pair)

问题是,这花费了很多时间,并且由于卡住而无法使用计算机。

有更好的方法吗?

2 个答案:

答案 0 :(得分:4)

您可以懒洋洋地做而不存储它们:

pairs = filter(lambda x: x[0] != x[1], itertools.product(indexes, indexes))

如果使用 itertools.ifilter

,请使用python2

使用itertools的想法是,您不需要预先计算所有内容,而只需一次计算一项(计算)。

我进行了@Deepak Saini的时间比较,即live here

import numpy as np
import itertools

indexes = np.arange(1000)

def pairs(indexes):
  pairs = []
  for pair in itertools.product(indexes, indexes):
      if pair[0]!=pair[1]:
          pairs.append(pair)
  return pairs

def iter_pairs(indexes):
  return filter(lambda x: x[0] != x[1], itertools.product(indexes, indexes))

def iter_pairs_no_lambda(indexes):
  def comp(x):
    return x[0] != x[1]
  return filter(comp, itertools.product(indexes, indexes))

import time
for f in (pairs, iter_pairs, iter_pairs_no_lambda):
  print(f.__name__)
  t1 = time.time()
  res = f(indexes)
  print("Took {}".format(time.time() -  t1))

以下结果:

pairs
Took 1.012538194656372
iter_pairs
Took 0.04567384719848633
iter_pairs_no_lambda
Took 0.0002455711364746094

答案 1 :(得分:0)

import numpy as np

a = np.asarray(indexes)
b = np.copy(a)

while np.any(a == b):
    b = np.random.choice(a, size=a.shape[0], replace=False)

并且应该非常快