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'}]
添加回答
举报