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

如何从列表中筛选出和等于给定值的不重复子集?

问题原因

itertools.combinations是基于元素位置生成组合的,你的原数组存在多个重复值(2个3、2个2),不同位置的同值元素会生成值完全相同的组合,再加上组合内部元素顺序不同也会被判定为不同组合,最终就出现了大量重复结果。

解决方法

轻量实现(小数据量适用)

对每个匹配的组合先做排序消除顺序影响,再存入集合自动去重即可,修改后代码如下:

from itertools import combinations
nums = [4,3,2,3,5,2,1]
res_set = set()
# 注意原代码遍历范围是range(1, len(nums)),会漏掉长度等于数组长度的组合,这里修正为len(nums)+1
for i in range(1, len(nums)+1):
    for comb in combinations(nums, i):
        if sum(comb) == 5:
            # 排序后转元组存入集合,自动去除重复值组合
            res_set.add(tuple(sorted(comb)))
# 转列表后可自行调整输出顺序
res = list(res_set)
print(res)

运行输出为:[(1, 4), (1, 2, 2), (2, 3), (5,)],你给出的预期输出里的重复(2,3)属于笔误,和为5的无重复值子集本身不包含重复的(2,3)。

高效实现(大数据量适用)

如果数组长度较大,用combinations会生成大量无效组合浪费性能,推荐用回溯剪枝方法,天然避免重复组合生成:

def get_unique_subsets(nums, target):
    nums.sort()
    res = []
    def backtrack(start_idx, cur_path, cur_sum):
        if cur_sum == target:
            res.append(tuple(cur_path))
            return
        if cur_sum > target:
            return
        for i in range(start_idx, len(nums)):
            # 同层跳过重复元素,避免生成重复组合
            if i > start_idx and nums[i] == nums[i-1]:
                continue
            cur_path.append(nums[i])
            backtrack(i+1, cur_path, cur_sum + nums[i])
            cur_path.pop()
    backtrack(0, [], 0)
    return res

nums = [4,3,2,3,5,2,1]
print(get_unique_subsets(nums, 5))

运行输出和上述方案一致,计算效率更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 21:27:03