如何获取列表元素的所有可能组合?

2024-04-18 20:46:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个包含15个数字的列表,我需要编写一些代码来生成这些数字的所有32768个组合。

我发现some code(通过google)显然可以做到我想要的,但是我发现代码相当不透明,并且对使用它很谨慎。另外我觉得一定有更优雅的解决方案。

唯一发生在我身上的事情就是循环遍历十进制整数1–32768并将它们转换为二进制,然后使用二进制表示作为筛选来挑选合适的数字。

有人知道更好的方法吗?也许用map()


Tags: 方法代码map列表google二进制code数字
3条回答

This answer遗漏了一个方面:OP要求所有组合。。。不仅仅是长度“r”的组合。

所以你要么要循环所有长度的“L”:

import itertools

stuff = [1, 2, 3]
for L in range(0, len(stuff)+1):
    for subset in itertools.combinations(stuff, L):
        print(subset)

或者——如果你想变得时髦(或者让后面读你代码的人的大脑弯曲),你可以生成“combinations()”生成器链,并遍历它:

from itertools import chain, combinations
def all_subsets(ss):
    return chain(*map(lambda x: combinations(ss, x), range(0, len(ss)+1)))

for subset in all_subsets(stuff):
    print(subset)

下面是一个懒惰的一行程序,也使用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

需要考虑的事项:

  • 这要求您可以在items上调用len(...)(解决方法:如果items类似于iterable的生成器,请首先使用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'}]

看看itertools.combinations

itertools.combinations(iterable, r)

Return r length subsequences of elements from the input iterable.

Combinations are emitted in lexicographic sort order. So, if the input iterable is sorted, the combination tuples will be produced in sorted order.

从2.6开始,包括电池!

相关问题 更多 >