You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从含重复元素的列表中获取所有不重复的组合?

解决带重复元素列表的组合去重问题

嘿,我完全懂你遇到的这个问题!当用itertools.combinations()处理带重复元素的列表时,确实会冒出一堆内容重复的组合——毕竟这个函数是靠元素的索引来生成组合的,哪怕值一样,只要位置不同,它就会当成不同的组合来生成,就像你例子里的(7,2,2)出现三次,就是因为三个2的索引不一样。

下面给你两种实用的解决方案,帮你得到想要的唯一组合:

方法一:生成后去重(简单直接)

如果你的列表元素不多,直接先生成所有组合,再用集合去重是最省事的方式。集合会自动剔除内容重复的元组,之后我们再按组合长度和元素排序,就能得到整齐的结果:

import itertools

array = [2,2,2,7]
all_combinations = []
# 生成所有长度的组合(从0个元素到全列表)
for r in range(len(array) + 1):
    all_combinations.extend(itertools.combinations(array, r))
# 去重+排序:先按组合长度排序,再按元素值排序
unique_combinations = sorted(set(all_combinations), key=lambda x: (len(x), x))
print(unique_combinations)

输出结果:

[(), (2,), (7,), (2, 2), (2, 7), (2, 2, 2), (2, 2, 7), (2, 2, 2, 7)]

方法二:提前避免生成重复组合(高效优化)

如果你的列表很大,生成所有组合再去重会浪费内存和时间。这时候可以先给列表排序,然后在生成组合时跳过重复元素,从根源上避免重复组合的产生:

def get_unique_combinations(arr):
    arr.sort()
    result = [()]  # 初始包含空组合
    start_idx = 0
    
    for i in range(len(arr)):
        # 遇到重复元素时,只基于上一轮新增的组合来扩展
        if i > 0 and arr[i] == arr[i-1]:
            prev_result_length = len(result)
            # 遍历上一轮新增的组合,添加当前元素
            for combo in result[start_idx:prev_result_length]:
                result.append(combo + (arr[i],))
            start_idx = prev_result_length
        else:
            # 非重复元素时,基于所有已有组合扩展
            start_idx = len(result)
            # 要copy一份结果,避免遍历过程中修改原列表导致的问题
            for combo in result.copy():
                result.append(combo + (arr[i],))
    
    # 按组合长度排序输出
    return sorted(result, key=lambda x: len(x))

array = [2,2,2,7]
print(get_unique_combinations(array))

这个方法的核心思路是:排序后,相同元素会挨在一起,当处理重复元素时,只在上一次处理该元素时新增的组合基础上添加当前元素,这样就不会生成重复的组合了。

内容的提问来源于stack exchange,提问作者user7040867

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:40:42