Choose at random from combinations

后端 未结 3 1173
执笔经年
执笔经年 2020-12-01 21:28

I can make a list of all combinations using list(itertools.combinations(range(n), m)) but this will typically be very large.

Given

相关标签:
3条回答
  • 2020-12-01 21:35

    A generator would be more memory efficient for iteration:

    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)] 
    
    0 讨论(0)
  • 2020-12-01 21:50

    In the itertools module there is a recipe for returning a random combination from an iterable. Below are two versions of the code, one for Python 2.x and one for Python 3.x - in both cases you are using a generator which means that you are not creating a large iterable in memory.

    Assumes 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)
    

    In your case then it would be simple to do:

    >>> 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)
    

    In the case of Python 3.x

    In the case of Python 3.x you replace the xrange call with range but the use-case is still the same.

    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)
    
    0 讨论(0)
  • 2020-12-01 21:57

    From 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)
    
    0 讨论(0)
提交回复
热议问题