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 been doing is using:
x = 3
y = 2
import random
output = random.sample(input, y)
# ['mordor', 'thingol']
but if I repeat this then I will have repeats.
I would like the output to be something like
[['mordor', 'thingol'], ['melian', 'hithlum'], ['beleriand', 'eol']]
since I chose x = 3 (3 lists) of size y = 2 (2 elements per list).
def random_generator(x,y):
....
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
def random_generator(seq, n, m):
rand_seq = seq[:] # make a copy to avoid changing input argument
random.shuffle(rand_seq)
lists = []
limit = n-1
for i,group in enumerate(itertools.izip(*([iter(rand_seq)]*m))):
lists.append(group)
if i == limit: break # have enough
return 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-1
for i,group in enumerate(itertools.izip(*([iter(rand_seq)]*m))):
yield group
if i == limit: break
pprint([group for group in random_generator_iterator(words, 3, 2)])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With