[英]Recursively find all combinations of list
問題陳述
我想從我的列表中獲取所有可能的組合(包括空列表)。
到目前為止,我的代碼是:
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]))
我的 output 是一個空列表
[]
我想要這個 Output:
[[], [1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]
我很確定我的回報是不對的。
非常感謝任何幫助。
可以這樣找到遞歸關系:“列表l
的組合要么使用l
的最后一個元素,要么不使用。”
所以我們遞歸地找到子列表l[:-1]
的組合(包含除最后一個元素之外的所有元素的子列表); 然后我們要么添加或不添加最后一個元素。
此遞歸需要一個基本案例。 基本情況是:如果列表為空,則唯一的組合是空組合。
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]]
遞歸關系很大,但不需要遞歸; for
循環可以很好地重復應用遞歸關系。
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]]
嘗試這個:
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]]
使用嵌套循環
first_list = [1,2,3]
second_list = ['a', 'b']
L = [[]]
for f in first_list:
for s in second_list:
L.append((f,s))
大號:
[[], (1, 'a'), (1, 'b'), (2, 'a'), (2, 'b'), (3, 'a'), (3, 'b')]
這是你想做的嗎?
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]
您也應該傳遞您的result
列表,如下所示。 但我認為這個遞歸 function 並沒有做你想做的事。
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]))
結果:
>>> python3 test.py
[5, 10, 5, 32, 10, 32, 5, 10, 5, 15, 10, 15, 5, 32, 5, 15, 32, ...
您無需遞歸即可獲得所有組合/排列:
排列:
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)
組合(此機制與您在問題中的描述相匹配):
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)
編輯:
當然,您可以從下面的示例中創建 function,並且可以將結果作為嵌套列表。
代碼:
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:
沒有itertools
模塊的解決方案:
代碼:
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]]
這是我的做法(作為生成器):
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]
或作為列表生成器:
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]]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.