Search code examples
python-3.xtuplesuniquecombinations

Pick from list of tuple combination pairs such that each tuple element appears at least twice


Suppose I have a list of tuples whose elements are are all possible pairings from a list:

i.e. matchup=[('Mike','John'),('Mike','Mary'),('Mike','Jane'),('John','Mary'),('John','Jane'),('Mary','Jane')...]

I'd like to reduce the list such that each person's name appears twice irrespective of whether they are the first element in the pairing or the second. A tuple element may be selected more than twice if it is not possible to create a new pair without doing so.

Thanks in advance.

edit: originally in the list, I used a for loop to pair each person with another person at random ala:

list=["John","Mike","Mary","Jane"]
pairing=[]
for person in list:
    for i in range(2):
        person2=random.sample(list(list),1)
        this_match=str(person)+str(person2)
        while this_match in pairing:
            person2=random.sample(list(list),1)
            this_match=str(person)+str(person2)
        pairing.append(this_match)

This led to same person duplications. My second try is this:

from itertools import combinations
import pandas as pd
from collections import Counter

possible_games = combinations(list, 2)

games = list(possible_games)
dupe_check=Counter(games)
print(dupe_check)
print (games, len(games))

However, I cannot reduce the elements of each tuple to appear as close to twice as possible.

One possible output might look like:

[('Mike','John'),('Mike','Mary'),('John','Mary'),("Mary","Jane"),("Jane","Mike")]

John appears twice. Jane appears twice. Mike appears three times in order for Jane to appear twice. Mary appears three times for Jane to appear twice.


Solution

  • The easiest way to get each name exactly twice is the following, I guess:

    lst = ["John", "Mike", "Mary", "Jane"]  # not shadowing 'list'
    
    pairs = list(zip(lst, lst[1:]+lst[:1]))
    pairs
    # [('John', 'Mike'), ('Mike', 'Mary'), ('Mary', 'Jane'), ('Jane', 'John')]
    

    This essentially circles the list and pairs each element with its two neighbours. If you need more randomness, you can shuffle the list beforehand or break up the list in chunks and apply this to the chunks.