0

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.

4
  • What have you tried, and what precisely is the problem with It? Commented Mar 21, 2017 at 10:14
  • I tried create two the same lists and use c = list(itertools.product(list1, list2)). But it creates output with the same name on the both sides. Commented Mar 21, 2017 at 10:15
  • Then give that minimal reproducible example. Did you do any research? Creating pairs of players is well trodden ground. For example: stackoverflow.com/q/5360220/3001761 Commented Mar 21, 2017 at 10:17
  • You should try itertools.product(your_list, repeat=2). Commented Mar 21, 2017 at 10:17

4 Answers 4

3

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')]]
Sign up to request clarification or add additional context in comments.

5 Comments

This is nice, but if I add one more name to the list it creates: [[('John', 'Jeff'), ('Peter', 'George', 'Simon')], [('John', 'Peter'), ('Jeff', 'George', 'Simon')], [('John', 'George'), ('Jeff', 'Peter', 'Simon')], [('John', 'Simon'), ('Jeff', 'Peter', 'George')], [('Jeff', 'Peter'), ('John', 'George', 'Simon')], [('Jeff', 'George'), ('John', 'Peter', 'Simon')], [('Jeff', 'Simon'), ('John', 'Peter', 'George')]]. So second tuple is size of 3 instead of 2, and there are no all combinations.
so what do you want the second tuple to be if there are 5 players?
Oh, I didn't say it. Sorry. When there is more that 4 players all remaining players just pause particular game and wait. So there are always 4 players, but generated from all players. And I want to generate list of all available games (so everyone have to play all generated games).
You should definitely add this to the question then
@sennin - I added an answer that I think satisfies your needs.
0

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')]]

3 Comments

you return the same answer twice, in a different order.
@beniev yes, deliberately so - as the question says, "Game allows to play rematch, so every pair of tuples should be repeated, but in different order"
Yes this answer seems to be ok
0

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'))]

Comments

-1

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')]

2 Comments

@sennin , Try this. This is the easiest way to get the desired output.
You return the same couple twice - and you don't return the complement....

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.