从组合中随机选择

时间:2014-03-06 16:07:48

标签: python

我可以使用list(itertools.combinations(range(n), m))制作所有组合的列表,但这通常非常大。

  

鉴于nm,如何在不首先构建大量列表的情况下随机均匀地选择组合?

4 个答案:

答案 0 :(得分:8)

itertools模块中,有一个从迭代中返回随机组合的方法。下面是代码的两个版本,一个用于Python 2.x,另一个用于Python 3.x - 在这两种情况下,您使用的是generator,这意味着您不会在内存中创建大型迭代。

假设Python 2.x

def random_combination(iterable, r):
    "Random selection from itertools.combinations(iterable, r)"
    pool = tuple(iterable)
    n = len(pool)
    indices = sorted(random.sample(xrange(n), r))
    return tuple(pool[i] for i in indices)

在你的情况下,这样做很简单:

>>> import random
>>> def random_combination(iterable, r):
    "Random selection from itertools.combinations(iterable, r)"
    pool = tuple(iterable)
    n = len(pool)
    indices = sorted(random.sample(xrange(n), r))
    return tuple(pool[i] for i in indices)
>>> n = 10
>>> m = 3
>>> print(random_combination(range(n), m))
(3, 5, 9) # Returns a random tuple with length 3 from the iterable range(10)

对于Python 3.x

对于Python 3.x,您将xrange调用替换为range,但用例仍然相同。

def random_combination(iterable, r):
    "Random selection from itertools.combinations(iterable, r)"
    pool = tuple(iterable)
    n = len(pool)
    indices = sorted(random.sample(range(n), r))
    return tuple(pool[i] for i in indices)

答案 1 :(得分:6)

来自http://docs.python.org/2/library/itertools.html#recipes

def random_combination(iterable, r):
    "Random selection from itertools.combinations(iterable, r)"
    pool = tuple(iterable)
    n = len(pool)
    indices = sorted(random.sample(xrange(n), r))
    return tuple(pool[i] for i in indices)

答案 2 :(得分:0)

生成器的迭代内存效率更高:

def random_combination(iterable,r):
    i = 0
    pool = tuple(iterable)
    n = len(pool)
    rng = range(n)
    while i < r:
        i += 1
        yield [pool[j] for j in random.sample(rng, r)] 

答案 3 :(得分:0)

我修改了 Jthorpe 的生成器,以便在您需要的组合数量大于您传递的迭代器长度时工作:

def random_combination(iterable,r):
    i = 0
    pool = tuple(iterable)
    n = len(pool)
    rng = range(n)
    while i < n**2/2:
        i += 1
        yield [pool[j] for j in random.sample(rng, r)]