3 回答

TA貢獻1797條經驗 獲得超6個贊
這個答案錯過了一個方面:OP要求所有組合...而不僅僅是長度“r”的組合。
所以你要么必須遍歷所有長度“L”:
import itertoolsstuff = [1, 2, 3]for L in range(0, len(stuff)+1): for subset in itertools.combinations(stuff, L): print(subset)
或者 - 如果你想變得時髦(或者在你之后讀取你的代碼的大腦彎曲) - 你可以生成“combination()”生成器鏈,并迭代:
from itertools import chain, combinationsdef all_subsets(ss): return chain(*map(lambda x: combinations(ss, x), range(0, len(ss)+1)))for subset in all_subsets(stuff): print(subset)

TA貢獻1799條經驗 獲得超9個贊
這是一個懶惰的單行,也使用itertools:
from itertools import compress, product
def combinations(items):
return ( set(compress(items,mask)) for mask in product(*[[0,1]]*len(items)) )
# alternative: ...in product([0,1], repeat=len(items)) )
這個答案背后的主要思想是:有2 ^ N個組合 - 與長度為N的二進制字符串的數量相同。對于每個二進制字符串,您選擇對應于“1”的所有元素。
items=abc * mask=###
|
V
000 ->
001 -> c
010 -> b
011 -> bc
100 -> a
101 -> a c
110 -> ab
111 -> abc
需要考慮的事項:
這就需要你可以調用len(...)的items(解決方法:如果items是像就像一臺發電機的迭代,用第一把它變成一個列表items=list(_itemsArg))
這要求迭代的順序items不是隨機的(解決方法:不要瘋狂)
這就要求項目是獨一無二的,要不然{2,2,1}并{2,1,1}都將崩潰{2,1}(解決方法:使用collections.Counter作為一個下拉更換set;它基本上是一個多集...盡管你可能需要在以后使用tuple(sorted(Counter(...).elements())),如果你需要它是可哈希)
演示
>>> list(combinations(range(4)))
[set(), {3}, {2}, {2, 3}, {1}, {1, 3}, {1, 2}, {1, 2, 3}, {0}, {0, 3}, {0, 2}, {0, 2, 3}, {0, 1}, {0, 1, 3}, {0, 1, 2}, {0, 1, 2, 3}]
>>> list(combinations('abcd'))
[set(), {'d'}, {'c'}, {'c', 'd'}, {'b'}, {'b', 'd'}, {'c', 'b'}, {'c', 'b', 'd'}, {'a'}, {'a', 'd'}, {'a', 'c'}, {'a', 'c', 'd'}, {'a', 'b'}, {'a', 'b', 'd'}, {'a', 'c', 'b'}, {'a', 'c', 'b', 'd'}]
添加回答
舉報