Python中寻找和为100的n个数所有组合的可变迭代实现方案
解决可变数量迭代变量的组合求和问题
嘿,这个问题我之前写数论小工具时碰到过,嵌套循环完全没法适配可变的n,不过Python里有个超巧妙的工具能搞定——itertools模块的combinations_with_replacement,不用写多层循环,一行生成所有可能的组合再筛选就行。
先从2个数的例子入手
常规的2个数求和写法是这样的,用嵌套循环找所有不重复的组合:
target_sum = 100 two_num_combs = [] for num1 in range(1, target_sum): num2 = target_sum - num1 if num2 >= num1: # 避免重复记录(1,99)和(99,1)这类等价组合 two_num_combs.append((num1, num2))
这个写法在n=2时没问题,但n=3就得写三层循环,n=5就要五层,代码会变得又长又难维护。
适配任意n的通用方法
核心思路是用combinations_with_replacement生成所有长度为n的不考虑顺序的正整数组合,再筛选出和为100的结果。这个函数会自动帮我们处理“不重复顺序”的问题,比如(1,1,98)只会出现一次,不会生成排列后的重复项。
直接上代码:
from itertools import combinations_with_replacement def find_sum_combinations(n, target): # 每个数至少为1,所以单个元素的最大值是 target - (n-1)*1(剩下n-1个数都是1) max_single_num = target - (n - 1) # 生成所有长度为n的正整数组合(不考虑顺序) all_possible_combs = combinations_with_replacement(range(1, max_single_num + 1), n) # 筛选出和为target的组合 return [comb for comb in all_possible_combs if sum(comb) == target]
代码说明
combinations_with_replacement(range(1, max_single_num +1), n):生成从1到max_single_num中选n个数的所有组合,允许元素重复(比如n=5时可以有(20,20,20,20,20)),且组合内元素是非降序排列的,避免重复结果。- 列表推导式直接筛选和为100的组合,逻辑清晰。
n=5时的结果示例
调用find_sum_combinations(5, 100)就能得到所有符合条件的5元组,部分结果如下:
[(1, 1, 1, 1, 96), (1, 1, 1, 2, 95), (1, 1, 1, 3, 94), ... (19, 19, 20, 21, 21), (19, 20, 20, 20, 21), (20, 20, 20, 20, 20)]
总共有156849个结果(这个数对应组合数学里的“整数分拆”问题:把100拆分成5个正整数的无序分拆数)。
额外补充:如果需要考虑顺序的情况
要是你需要的是排列(比如(1,99)和(99,1)算不同结果),那就把combinations_with_replacement换成product,不过要注意范围调整,同时结果会多很多:
from itertools import product def find_sum_permutations(n, target): all_possible_perms = product(range(1, target - n +2), repeat=n) return [perm for perm in all_possible_perms if sum(perm) == target]
不过这种情况一般不是“组合”的需求,所以还是优先用combinations_with_replacement。
内容的提问来源于stack exchange,提问作者lrh09
相关产品推荐
相关产品推荐

