Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making all possible combinations of a list

I need to be able to make a list that contains all possible combinations of an inputted list. For example the list [1,2,3] should return [1 [1,2] [1,3] 2 [2,3] 3 [1,2,3]] The list doesn't have to be in any particular order. On this site I've found lots of functions using the itertools but those are returning objects when I need just a list.

like image 420
Dean Avatar asked Dec 03 '11 23:12

Dean


People also ask

How do you find all combinations of a list excel?

Joining queries to find all combinations of two lists Once the queries from the tables are ready, go to Data > Get Data > Combine Queries > Merge to open the Merge dialog of Power Query. Select each table in the drop downs. Click on the column for each table to select them.

How do you generate all possible combinations of two lists in Python?

The unique combination of two lists in Python can be formed by pairing each element of the first list with the elements of the second list. Method 1 : Using permutation() of itertools package and zip() function. Approach : Import itertools package and initialize list_1 and list_2.


6 Answers

Simply use itertools.combinations. For example:

import itertools

lst = [1, 2, 3]
combs = []

for i in xrange(1, len(lst)+1):
    combs.append(i)
    els = [list(x) for x in itertools.combinations(lst, i)]
    combs.append(els)

Now combs holds this value:

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

Yes, it's slightly different from the sample output you provided, but in that output you weren't listing all possible combinations.

I'm listing the size of the combination before the actual list for each size, if what you need is simply the combinations (without the size, as it appears in your sample output) then try these other version of the code:

import itertools

lst = [1, 2, 3]
combs = []

for i in xrange(1, len(lst)+1):
    els = [list(x) for x in itertools.combinations(lst, i)]
    combs.extend(els)

Now combs holds this value:

[[1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]
like image 72
Óscar López Avatar answered Oct 09 '22 02:10

Óscar López


The itertools module indeed returns generators instead of lists, but:

  • Generators are often more efficient than lists (especially if you are generating a large number of combinations)
  • You can always convert generators to lists using list(...) when you really need to.

The chain and combinations functions of itertools work well, but you need to use Python 2.6 or greater:

import itertools

def all_combinations(any_list):
    return itertools.chain.from_iterable(
        itertools.combinations(any_list, i + 1)
        for i in xrange(len(any_list)))

You can then call this as such:

# as a generator
all_combinations([1,2,3])  # --> <itertools.chain at 0x10ef7ce10>

# as a list
list(all_combinations([1,2,3]))  # --> [(1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]

# as a list of lists
[list(l) for l in all_combinations([1,2,3])]  # --> [[1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]

If you haven't used generators before, note that you loop through them as if they were a list, such as this:

# a generator returned instead of list
my_combinations = all_combinations([1,2,3])

# this would also work if `my_combinations` were a list
for c in my_combinations:
    print "Combo", c

"""
Prints:
  Combo (1,)
  Combo (2,)
  Combo (3,)
  Combo (1, 2)
  Combo (1, 3)
  Combo (2, 3)
  Combo (1, 2, 3)
"""

The performance difference can be dramatic. If you compare the performance you'll see that the generator is much faster to create:

# as a generator
all_combinations(range(25))  # timing: 100000 loops, best of 3: 2.53 µs per loop

# as a list
list(all_combinations(range(25)))  # timing: 1 loops, best of 3: 9.37 s per loop

Note that it would still take some time to iterate through all the combinations in either case, but it can be a big win for you especially if you find what you're looking for early on.

like image 43
Arel Avatar answered Oct 09 '22 03:10

Arel


The functions from the itertools module return iterators. All you need to do to convert these into lists is call list() on the result.

However, since you will need to call itertools.combinations three separate times (once for each different length), you can just use list.extend to add all elements of the iterator to your final list.

Try the following:

import itertools
in_list = [1, 2, 3]
out_list = []
for i in range(1, len(in_list)+1):
    out_list.extend(itertools.combinations(in_list, i))

Or as a list comprehension:

out_list = [c for i in range(len(in_list)) for c in itertools.combinations(in_list, i+1)]

These will result in the following list:

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

If you want lists instead of tuples, and to convert the single length tuples to just the value, you can do the following:

out_list = [x[0] if len(x) == 1 else list(x) for x in out_list]
# [1, 2, 3, [1, 2], [1, 3], [2, 3], [1, 2, 3]]

Or to leave the single items as lists:

out_list = map(list, out_list)
like image 41
Andrew Clark Avatar answered Oct 09 '22 02:10

Andrew Clark


You could solve your problem using itertools.combinations inside of a loop:

>>> l = [1,2,3]
>>> comb = []
>>> for i in range(len(l)):
...   comb += itertools.combinations(l,i+1)
... 
>>> comb
[(1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]

And if you want them as a list:

>>> comb_list = [ list(t) for t in comb ]
>>> comb_list
[[1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]

EDIT: The first parameter of combinations is the iterable and the second one is the length of the resulting tuples (in this case, going from 1 to len(l)).

More about combinations: http://docs.python.org/library/itertools.html#itertools.combinations

like image 30
juliomalegria Avatar answered Oct 09 '22 01:10

juliomalegria


l = [1,2,3]
combs = reduce(lambda x, y: list(itertools.combinations(l, y)) + x, range(len(l)+1), [])

If you want a oneliner.

like image 43
Prafulla Mahesh Pallal Avatar answered Oct 09 '22 03:10

Prafulla Mahesh Pallal


I think it's worth boiling down the other answers here into a simple Python 3 example:

from itertools import chain, combinations

def all_combinations(array):
    return chain(*(list(combinations(array, i + 1)) for i in range(len(array))))

This returns an iterable, to view the values:

>>> print(list(all_combinations((1, 2, 3))))
[(1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]
like image 43
Ninjakannon Avatar answered Oct 09 '22 03:10

Ninjakannon