问题
Problem statement
I want to get all possible combinations out of my list (including the empty list).
My code so far is:
def combination(l):
result = []
for item in range(len(l)):
cut_list = l[:item] + l[item + 1:]
if len(cut_list) > 1:
combination(cut_list)
elif len(cut_list) == 1:
result += cut_list
return result
print(combination([1, 2, 3]))
My output is an empty List
[]
i want this Output:
[[], [1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]
I am pretty sure something with my return is not right.
Any help is extremely appreciated.
回答1:
A recurrence relation can be found this way: "A combination of list l
either uses the last element of l
, or it doesn't."
So we find recursively the combinations of sublist l[:-1]
(the sublist containing all elements except the last one); and then we either add or don't add the last element.
Recursive version
This recursion needs a base case. The base case is: if the list is empty, then the only combination is the empty combination.
def combinations(l):
if l:
result = combinations(l[:-1])
return result + [c + [l[-1]] for c in result]
else:
return [[]]
print(combinations([1,2,3]))
# [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]
Iterative version
The recurrence relation is great, but there is no need for recursion; for
-loops work very well to apply recurrence relations repeatedly.
def combinations(l):
result = [[]]
for x in l:
result = result + [c + [x] for c in result]
return result
print(combinations([1,2,3]))
# [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]
回答2:
Try this:
In [24]: import itertools
In [25]: l
Out[25]: [1, 2, 3]
In [26]: [sublist for item in [[list(x) for x in itertools.combinations(l,n)] for n in range(len(l)+1)] for sublist in item]
Out[26]: [[], [1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]
回答3:
Use nested loop
first_list = [1,2,3]
second_list = ['a', 'b']
L = [[]]
for f in first_list:
for s in second_list:
L.append((f,s))
L:
[[], (1, 'a'), (1, 'b'), (2, 'a'), (2, 'b'), (3, 'a'), (3, 'b')]
回答4:
this is what you wanted to do?
l = [3, 22, 10, 15, 32, 10, 5]
def f(ml: list):
a = []
for i1 in ml:
for i2 in ml:
if not i1 + i2 in a:
a.append(i1 + i2)
return a
print(f(l))
[6, 25, 13, 18, 35, 8, 44, 32, 37, 54, 27, 20, 42, 15, 30, 47, 64, 10]
回答5:
You should pass your result
list as well, like below. But I think this recursive function doesn't do that what you want to do.
def combination(l, result=[]):
for item in range(len(l)):
cut_list = l[:item] + l[item + 1:]
if len(cut_list) > 1:
combination(cut_list, result)
elif len(cut_list) == 1:
result += cut_list
return result
print(combination([3, 22, 10, 15, 32, 10, 5]))
Result:
>>> python3 test.py
[5, 10, 5, 32, 10, 32, 5, 10, 5, 15, 10, 15, 5, 32, 5, 15, 32, ...
You can get the all combinations/permutations without recursion:
Permutations:
import itertools
stuff = [1, 2, 3]
for L in range(0, len(stuff)+1):
for subset in itertools.permutations(stuff, L):
print(subset)
Output:
>>> python3 test.py
()
(1,)
(2,)
(3,)
(1, 2)
(1, 3)
(2, 1)
(2, 3)
(3, 1)
(3, 2)
(1, 2, 3)
(1, 3, 2)
(2, 1, 3)
(2, 3, 1)
(3, 1, 2)
(3, 2, 1)
Combinations (This mechanism matches with your description in your question):
import itertools
stuff = [1, 2, 3]
for L in range(0, len(stuff)+1):
for subset in itertools.combinations(stuff, L):
print(subset)
Output:
>>> python3 test.py
()
(1,)
(2,)
(3,)
(1, 2)
(1, 3)
(2, 3)
(1, 2, 3)
EDIT:
Of course, you can make a function from my below example and you can get the result as a nested list.
Code:
import itertools
def combination(l):
result = []
for L in range(0, len(l)+1):
for subset in itertools.combinations(l, L):
result.append(list(subset))
return result
print(combination([1, 2, 3]))
Output:
>>> python3 test.py
[[], [1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]
EDIT_2:
Solution without itertools
module:
Code:
def combinations(return_len, iterable):
if not return_len:
return [[]]
if not iterable:
return []
head = [iterable[0]]
tail = iterable[1:]
new_comb = [head + list_ for list_ in combinations(return_len - 1, tail)]
return new_comb + combinations(return_len, tail)
input_list = [1, 2, 3]
result = []
for n in range(0, len(input_list) + 1):
for single_result in combinations(n, input_list):
result.append(single_result)
print(result)
Output:
>>> python3 test.py
[[], [1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]
回答6:
Here's how I would do it (as a generator):
def combinations(aList):
yield []
for i,v in enumerate(aList,1):
yield from ([v]+c for c in combinations(aList[i:]))
for combo in combinations([1,2,3]): print(combo)
[]
[1]
[1, 2]
[1, 2, 3]
[1, 3]
[2]
[2, 3]
[3]
or as a list builder:
def combinations(aList):
return [[]] + [ [v]+c for i,v in enumerate(aList,1)
for c in combinations(aList[i:]) ]
print( combinations([1,2,3]) )
[[], [1], [1, 2], [1, 2, 3], [1, 3], [2], [2, 3], [3]]
来源:https://stackoverflow.com/questions/65181109/recursively-find-all-combinations-of-list