1

I have a list of, say, 3 players:

[1, 2, 3]

How can I generate, in python, a list of lists, of the form:

[[1], [2], [3], [1,2], [1,3], [2,3], [1,2,3]]

representing all teams that can be formed with the above players?

Qubix
  • 4,161
  • 7
  • 36
  • 73
  • 2
    Does this answer your question? [Making all possible combinations of a list](https://stackoverflow.com/questions/8371887/making-all-possible-combinations-of-a-list) – Chris Jan 15 '20 at 15:14
  • @Qubix Check the answer I posted it shows `itertools` approach, as well as recursive approach, might help you. – Ch3steR Jan 15 '20 at 16:38

5 Answers5

2

You could use itertools.combinations() where we can set r parameter to all lengths from 1 to length of our list (x), to get all possible combinations that are going to be flattened in list comprehension.

from itertools import combinations

x = [1, 2, 3]
result = [c for i in range(1, len(x)+1) for c in combinations(x, i)]
print(result)  # -> [(1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]
Filip Młynarski
  • 3,534
  • 1
  • 10
  • 22
2

Use https://docs.python.org/3/library/itertools.html#itertools.combinations

It does exactly what you want.

import itertools
players = [1, 2, 3]
print(list(itertools.chain.from_iterable(itertools.combinations(players, r) for r in range(1, len(players) + 1))))

Output:

[(1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]

This is probably the most efficient answer due to the use of itertools.chain

Hack5
  • 3,244
  • 17
  • 37
1

You can use itertools.combinations with a given size to generate fixed size combinations. In order to generalize, you can just use a for loop over all the sizes. The code would look like this:

import itertools

my_list = [1, 2, 3]
for L in range(0, len(my_list)+1):
    for subset in itertools.combinations(my_list, L):
        print(subset)
ibarrond
  • 6,617
  • 4
  • 26
  • 45
  • That's pretty inefficient. You should use an itertools.chain to optimise it with C extensions if you have a very large team size – Hack5 Jan 15 '20 at 17:17
  • If the question had asked for performance, there are clearly better options out there. You can also put Cython in the mix, try speeding up with NumPy and Numba or parallelize with dash. My point is, there is no such request. Programmer time can be more expensive than CPU time, thus you need a reason to complexify things. – ibarrond Jan 15 '20 at 23:26
  • But the faster approach is also faster to code; it is only 1 line of processing – Hack5 Jan 16 '20 at 07:10
0

You can use itertools. What you want to do is generate powerset of the given list.

>>> import itertools
>>> a=[1,2,3]
>>> out=[]
>>> for i in range(len(a)+1):
    out+=list(itertools.combinations(a,i))


>>> out
[(), (1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]
>>> 

You can write recursive function to generate powerset as follows:

>>> def powerset(s,idx,curr,out):
    if idx==len(s):
        out.append(curr)
        return
    (powerset(s,idx+1,curr+[s[idx]],out))
    (powerset(s,idx+1,curr,out))
    return sorted(out,key=lambda x:len(x))

>>> z=powerset(a,0,[],[])
>>> z
[[], [1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]
Ch3steR
  • 20,090
  • 4
  • 28
  • 58
0

Itertools is you friend for these kind of operations:

import itertools

l = [1, 2, 3]

l = [list(x) for y in range(1,len(l)+1) for x in itertools.combinations(l,y) ]
print(l)

Gives:

[[1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]
kleerofski
  • 423
  • 4
  • 8