sennin
sennin

Reputation: 8972

Combinations of two lists in python

I have a list:

list = ['john','jeff','george','peter']

I want to create following output:

[
  [('john','jeff'),('george','peter')],
  [('john','george'),('jeff','peter')],
  [('john','peter'),('jeff','george')],
  [('george','peter'),('john','jeff')],
  [('jeff','peter'),('john','george')],
  [('jeff','george'),('john','peter')]
]

Generally I want to create all player combinations for 2 vs 2 game. Inside one output line, one name can show only once (one player can play in only one team at a time). Game allows to play rematch, so every pair of tuples should be repeated, but in different order (different order of tuples, no different order of items in tuple).

When the list has more than 4 elements, for example 5, the output should be like that:

list = ['john','jeff','george','peter','simon']

[
  [('john','jeff'),('george','peter')],
  [('john','george'),('jeff','peter')],
  [('john','george'),('jeff','simon')],
  [('john','peter'),('jeff','george')],
  [('john','simon'),('jeff','george')],
  [('george','peter'),('john','jeff')],
  [('george','simon'),('john','jeff')],
  [('jeff','peter'),('john','george')],
  [('jeff','george'),('john','peter')],
  [('jeff','george'),('john','peter')]
  ...
]

So there is always 4 players in one game. Rest of players just wait and are not involved in particular game.

Upvotes: 0

Views: 3562

Answers (4)

Miriam Farber
Miriam Farber

Reputation: 19634

You can do it like that:

import itertools
l = set(['john','jeff','george','peter'])
m=list(itertools.combinations(l, 2))
res=[[i,tuple(l.symmetric_difference(i))] for i in m]

m is a list of all the pairs, and res associates each pair with its complement. So the output is

[[('john', 'jeff'), ('peter', 'george')],
 [('john', 'peter'), ('jeff', 'george')],
 [('john', 'george'), ('jeff', 'peter')],
 [('jeff', 'peter'), ('john', 'george')],
 [('jeff', 'george'), ('john', 'peter')],
 [('peter', 'george'), ('john', 'jeff')]]

Edit: If there are more than 4 elements in the list, this should work:

import itertools
l = set(['john','jeff','george','peter','a'])
four_tuples=list(itertools.combinations(l, 4))
pairs=[(set(i),list(itertools.combinations(i, 2))) for i in four_tuples]
pair_and_comp=[[[r,tuple(el[0].symmetric_difference(r))] for r in el[1:][0]] for el in pairs]
res=sum(pair_and_comp,[])
res

The output is

[[('john', 'jeff'), ('peter', 'george')],
 [('john', 'peter'), ('jeff', 'george')],
 [('john', 'george'), ('jeff', 'peter')],
 [('jeff', 'peter'), ('john', 'george')],
 [('jeff', 'george'), ('john', 'peter')],
 [('peter', 'george'), ('john', 'jeff')],
 [('john', 'jeff'), ('peter', 'a')],
 [('john', 'peter'), ('jeff', 'a')],
 [('john', 'a'), ('jeff', 'peter')],
 [('jeff', 'peter'), ('john', 'a')],
 [('jeff', 'a'), ('john', 'peter')],
 [('peter', 'a'), ('john', 'jeff')],
 [('john', 'jeff'), ('george', 'a')],
 [('john', 'george'), ('jeff', 'a')],
 [('john', 'a'), ('jeff', 'george')],
 [('jeff', 'george'), ('john', 'a')],
 [('jeff', 'a'), ('john', 'george')],
 [('george', 'a'), ('john', 'jeff')],
 [('john', 'peter'), ('george', 'a')],
 [('john', 'george'), ('peter', 'a')],
 [('john', 'a'), ('peter', 'george')],
 [('peter', 'george'), ('john', 'a')],
 [('peter', 'a'), ('john', 'george')],
 [('george', 'a'), ('john', 'peter')],
 [('jeff', 'peter'), ('george', 'a')],
 [('jeff', 'george'), ('peter', 'a')],
 [('jeff', 'a'), ('peter', 'george')],
 [('peter', 'george'), ('jeff', 'a')],
 [('peter', 'a'), ('jeff', 'george')],
 [('george', 'a'), ('jeff', 'peter')]]

Upvotes: 3

Binyamin Even
Binyamin Even

Reputation: 3382

This should do the trick for you:

from itertools import combinations
l = ['john','jeff','george','peter','beni']
x= list(combinations(l,2))
y=list(combinations(x,2))
remove_dup =lambda y: y if len(set(y[0])-set(y[1]))==2 else None
answer=[remove_dup(t) for t in y if remove_dup(t) is not None]

answer:

[(('john', 'jeff'), ('george', 'peter')),
 (('john', 'jeff'), ('george', 'beni')),
 (('john', 'jeff'), ('peter', 'beni')),
 (('john', 'george'), ('jeff', 'peter')),
 (('john', 'george'), ('jeff', 'beni')),
 (('john', 'george'), ('peter', 'beni')),
 (('john', 'peter'), ('jeff', 'george')),
 (('john', 'peter'), ('jeff', 'beni')),
 (('john', 'peter'), ('george', 'beni')),
 (('john', 'beni'), ('jeff', 'george')),
 (('john', 'beni'), ('jeff', 'peter')),
 (('john', 'beni'), ('george', 'peter')),
 (('jeff', 'george'), ('peter', 'beni')),
 (('jeff', 'peter'), ('george', 'beni')),
 (('jeff', 'beni'), ('george', 'peter'))]

Upvotes: 0

asongtoruin
asongtoruin

Reputation: 10359

How about the following:

from itertools import combinations
from pprint import pprint

names = ['john', 'jeff', 'george', 'peter', 'ringo']

combos = list(combinations(names, 2))
pairs = [[x, y] for x in combos for y in combos if not set(x).intersection(set(y))]

pprint(pairs)

combinations gives us all pairs of length 2 (we convert this to a list so we don't exhaust it when iterating over it). set(x).intersection(set(y)) finds if there are any items in common between x and y, and we want to keep the combination if this is not the case.

This prints:

[[('john', 'jeff'), ('george', 'peter')],
 [('john', 'jeff'), ('george', 'ringo')],
 [('john', 'jeff'), ('peter', 'ringo')],
 [('john', 'george'), ('jeff', 'peter')],
 [('john', 'george'), ('jeff', 'ringo')],
 [('john', 'george'), ('peter', 'ringo')],
 [('john', 'peter'), ('jeff', 'george')],
 [('john', 'peter'), ('jeff', 'ringo')],
 [('john', 'peter'), ('george', 'ringo')],
 [('john', 'ringo'), ('jeff', 'george')],
 [('john', 'ringo'), ('jeff', 'peter')],
 [('john', 'ringo'), ('george', 'peter')],
 [('jeff', 'george'), ('john', 'peter')],
 [('jeff', 'george'), ('john', 'ringo')],
 [('jeff', 'george'), ('peter', 'ringo')],
 [('jeff', 'peter'), ('john', 'george')],
 [('jeff', 'peter'), ('john', 'ringo')],
 [('jeff', 'peter'), ('george', 'ringo')],
 [('jeff', 'ringo'), ('john', 'george')],
 [('jeff', 'ringo'), ('john', 'peter')],
 [('jeff', 'ringo'), ('george', 'peter')],
 [('george', 'peter'), ('john', 'jeff')],
 [('george', 'peter'), ('john', 'ringo')],
 [('george', 'peter'), ('jeff', 'ringo')],
 [('george', 'ringo'), ('john', 'jeff')],
 [('george', 'ringo'), ('john', 'peter')],
 [('george', 'ringo'), ('jeff', 'peter')],
 [('peter', 'ringo'), ('john', 'jeff')],
 [('peter', 'ringo'), ('john', 'george')],
 [('peter', 'ringo'), ('jeff', 'george')]]

Upvotes: 0

Dheeraj
Dheeraj

Reputation: 1202

try itertools with permutations()

import itertools
my_list = ['john','jeff','george','peter']
paired = []
for pair in itertools.permutations(my_list, 2):
    paired.append(pair)
print paired

[('john', 'jeff'), ('john', 'george'), ('john', 'peter'), ('jeff', 'john'), ('jeff', 'george'), ('jeff', 'peter'), ('george', 'john'), ('george', 'jeff'), ('george', 'peter'), ('peter', 'john'), ('peter', 'jeff'), ('peter', 'george')]

Upvotes: -1

Related Questions