Skip to content Skip to sidebar Skip to footer

Mutually Exclusive Random Sampling From A List

input = ['beleriand','mordor','hithlum','eol','morgoth','melian','thingol'] I'm having trouble creating X number of lists of size Y without repeating any elements. What I have bee

Solution 1:

You can simply shuffle the original list and then generate n groups of m elements successively from it. There may be fewer or more than that number of groups possible. Note thatinputis the name of a Python built-in function, so I renamed itwords.

import itertools
from pprint import pprint
import random

defrandom_generator(seq, n, m):
    rand_seq = seq[:]  # make a copy to avoid changing input argument
    random.shuffle(rand_seq)
    lists = []
    limit = n-1for i,group inenumerate(itertools.izip(*([iter(rand_seq)]*m))):
        lists.append(group)
        if i == limit: break# have enoughreturn lists

words = ['beleriand', 'mordor', 'hithlum', 'eol', 'morgoth', 'melian', 'thingol']
pprint(random_generator(words, 3, 2))

Output:

[('mordor', 'hithlum'), ('thingol', 'melian'), ('morgoth', 'beleriand')]

It would be more Pythonic to generate the groups iteratively. The above function could easily be turned into generator by making ityieldeach group, one-by-one, instead of returning them all in a relatively much longer list-of-lists:

def random_generator_iterator(seq, n, m):
    rand_seq = seq[:]
    random.shuffle(rand_seq)
    limit = n-1for i,groupinenumerate(itertools.izip(*([iter(rand_seq)]*m))):
        yieldgroupif i == limit: breakpprint([groupforgroupin random_generator_iterator(words, 3, 2)])

Solution 2:

rather than randomly taking two things from your list, just randomize your list and iterate through it to create your new array of the dimensions you specify!

importrandommy_input= ['beleriand','mordor','hithlum','eol','morgoth','melian','thingol']
def random_generator(array,x,y):
    random.shuffle(array)
    result = []
    count = 0while count < x:
        section = []
        y1 = y * county2= y * (count + 1)
        for i in range(y1,y2):
            section.append(array[i])
        result.append(section)
        count += 1return result
print random_generator(my_input,3,2)

Solution 3:

You could use random.sample in combination with the itertools.grouper recipe.

input = ['beleriand','mordor','hithlum','eol','morgoth','melian','thingol']
import itertools
import random
defgrouper(iterable,group_size):
    return itertools.izip(*([iter(iterable)]*group_size))

defrandom_generator(x,y):
    k = x*y
    sample = random.sample(input,k)
    returnlist(grouper(sample,y))

print random_generator(3,2)
print random_generator(3,2)
print random_generator(3,2)
print random_generator(3,2)
print random_generator(3,2)
print random_generator(3,2)

for one run, this results in:

[('melian', 'mordor'), ('hithlum', 'eol'), ('thingol', 'morgoth')][('hithlum', 'thingol'), ('mordor', 'beleriand'), ('morgoth', 'eol')][('morgoth', 'beleriand'), ('melian', 'thingol'), ('hithlum', 'mordor')][('beleriand', 'thingol'), ('melian', 'hithlum'), ('eol', 'morgoth')][('mordor', 'hithlum'), ('eol', 'beleriand'), ('melian', 'morgoth')][('mordor', 'melian'), ('thingol', 'beleriand'), ('morgoth', 'eol')]

And the next run:

[('mordor', 'thingol'), ('eol', 'hithlum'), ('melian', 'beleriand')][('eol', 'beleriand'), ('mordor', 'melian'), ('hithlum', 'thingol')][('hithlum', 'mordor'), ('thingol', 'morgoth'), ('melian', 'eol')][('morgoth', 'eol'), ('mordor', 'thingol'), ('melian', 'beleriand')][('melian', 'morgoth'), ('mordor', 'eol'), ('thingol', 'hithlum')][('mordor', 'morgoth'), ('hithlum', 'thingol'), ('eol', 'melian')]

Post a Comment for "Mutually Exclusive Random Sampling From A List"