Reputation: 648
I looked up many related questions, but no one actually answers me how to receive ALL combinations of the elemets in a list. For example, with this input list
input_list = ["apple", "orange", "carrot"]
I would like to have this list:
output_list = [ ["apple"], ["orange"], ["carrot"], ["apple", "orange"], ["apple", "carrot"], ["orange", "carrot"], ["apple", "orange", "carrot"]]
i.e. I also want to have the single entries included, how can I do this?
Upvotes: 0
Views: 286
Reputation: 27495
You are looking for the powerset
itertools recipe:
from itertools import chain, combinations
def powerset(iterable):
"powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
s = list(iterable)
return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
>>> input_list = ["apple", "orange", "carrot"]
>>> print(list(map(list, powerset(input_list)))[1:])
[['apple'], ['orange'], ['carrot'],['apple', 'orange'], ['apple', 'carrot'], ['orange', 'carrot'], ['apple', 'orange', 'carrot']]
Upvotes: 2
Reputation: 531480
The itertools
documentation provides a set of useful recipes for things easily implemented using the module; among them is a powerset generator:
def powerset(iterable):
"powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
s = list(iterable)
return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
Given your list of strings, you'll get a list of tuples.
>>> list(powerset(input_list))
[(), ('apple',), ('orange',), ('carrot',), ('apple', 'orange'), ('apple', 'carrot'), ('orange', 'carrot'), ('apple', 'orange', 'carrot')]
The empty tuple is easily filtered, and the tuples can be converted to lists if necessary.
>>> list(list(x) for x in powerset(input_list) if x != ())
[['apple'], ['orange'], ['carrot'], ['apple', 'orange'], ['apple', 'carrot'], ['orange', 'carrot'], ['apple', 'orange', 'carrot']]
Upvotes: 1
Reputation: 2402
a oneliner answer is:
[list(j) for i in range(len(input_list )) for j in itertools.combinations(input_list , i+1)]
the first loop (i
) goes over all different combinations and creates the combination object, then the second loop (j
) goes over every element of the combination and makes a list of it then appends it to the original list. The output is as you want, without changing anything.
Upvotes: 1
Reputation: 6132
This is almost what you're looking for, minus some formatting:
from itertools import combinations
input_list = ["apple", "orange", "carrot"]
combis = [[i for i in combinations(input_list, 1)], [i for i in combinations(input_list, 2)], [i for i in combinations(input_list, 3)]]
Output:
[[('apple',), ('orange',), ('carrot',)],
[('apple', 'orange'), ('apple', 'carrot'), ('orange', 'carrot')],
[('apple', 'orange', 'carrot')]]
Upvotes: 1