Jivan
Jivan

Reputation: 23078

Random pairs without repeats in Python (numpy or itertools)

I have a list of people and want to generate a number of random pairs or triplets so that every person in the list belongs to exactly one pair or triplet (no more, no less).

Example:

>>> people = ["John", "Paul", "George", "Ringo", "David", "Roger", "Richard", "Nick", "Syd"]

>>> generate_random_pairs(people)

[
    ("John", "George"),
    ("Paul", "David"),
    ("Roger", "Nick"),
    ("Ringo", "Richard", "Syd")
]

I've tried different ideas using numpy.random.choice, numpy.random.sample or itertools.permutations but none of them seem to work.

Upvotes: 4

Views: 974

Answers (2)

RootTwo
RootTwo

Reputation: 4418

Use the grouper() recipe from itertools:

from itertools import zip_longest
from random import shuffle

def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks of size n."
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return zip_longest(*args, fillvalue=fillvalue)

people = ["John", "Paul", "George", "Ringo", "David", "Roger", "Richard", "Nick", "Syd"]

shuffle(people)

list(grouper(people, 3, ''))

Example output:

[('Ringo', 'George', 'Syd'),
 ('Richard', 'David', 'John'),
 ('Paul', 'Roger', 'Nick')]

Upvotes: 2

Jivan
Jivan

Reputation: 23078

Building on jonrsharpe's comment

import numpy as np

people = ["John", "Paul", "George", "Ringo", "David", "Roger", "Richard", "Nick", "Syd"]

shuffled = np.random.permutation(people)

pairs_or_triplets = [list(a) for a in np.array_split(shuffled, len(shuffled) / 2)]

Upvotes: 1

Related Questions