Skip to main content
 首页 » 编程设计

Python组合

2025年05月04日23落叶

假设我有一个如下所示的 Python 列表:

[1, 2, 3, 4] 

我希望能够返回包含两个或多个数字的所有组合的列表列表。值的顺序无关紧要,因此 1,2 与 2,1 相同。我还想返回另一个列表,其中包含每个组合中没有的值。例如:

Combination 1,2 / Remainder 3,4 
Combination 2,3 / Remainder 1,4 
Combination 1,2,3 / Remainder 4 
Combination 1,2,3,4/ Remainder - 

上面的返回列表是

combination = [[1,2], [2,3], [1,2,3], [1,2,3,4]] 
remainder = [[3,4], [1,4], [4], []] 

我只展示了几个例子......

我意识到第一部分可能可以使用 itertools.combinations 来实现,但是我如何在不循环的情况下返回组合中未使用的那些值?

请您参考如下方法:

基于 Nunzio 的想法,但不是将特定范围内的数字转换为二进制,您可以只使用 itertools.product 来获取 1 和的所有组合0(或 True 和 False),然后将其用作过滤“输入”和“输出”的掩码。

>>> lst = [1,2,3] 
>>> products = list(product([1,0], repeat=len(lst))) 
>>> [[lst[i] for i, e in enumerate(p) if e] for p in products] 
[[1, 2, 3], [1, 2], [1, 3], [1], [2, 3], [2], [3], []] 
>>> [[lst[i] for i, e in enumerate(p) if not e] for p in products] 
[[], [3], [2], [2, 3], [1], [1, 3], [1, 2], [1, 2, 3]] 

您还可以为该enumerate 理解定义一个函数,并一次性完成这两个部分:

>>> mask = lambda lst, p, v: [lst[i] for i, e in enumerate(p) if e == v] 
>>> [(mask(lst, p, 1), mask(lst, p, 0)) for p in product([1,0], repeat=len(lst))] 
[([1, 2, 3], []), 
 ([1, 2], [3]), 
 ([1, 3], [2]), 
 ([1], [2, 3]), 
 ([2, 3], [1]), 
 ([2], [1, 3]), 
 ([3], [1, 2]), 
 ([], [1, 2, 3])] 

如果您只想与“in”列表中的 2 个或更多个组合,您可以添加一个条件:

>>> [(mask(lst, p, 1), mask(lst, p, 0)) for p in product([1,0],repeat=len(lst)) if sum(p) >= 2] 

或者使用 numpy 数组并利用 numpy 的高级索引:

>>> arr = np.array([1,2,3]) 
>>> [(arr[p==1], arr[p==0]) for p in map(np.array, product([1,0], repeat=len(arr)))] 
[(array([1, 2, 3]), array([])), 
 (array([1, 2]), array([3])), 
 (array([1, 3]), array([2])), 
 (array([1]), array([2, 3])), 
 (array([2, 3]), array([1])), 
 (array([2]), array([1, 3])), 
 (array([3]), array([1, 2])), 
 (array([]), array([1, 2, 3]))]