依赖一个参数的未确定数量的for循环
我正在尝试做以下事情:有一个函数接收两个数字 n 和 d,其中 n 是循环的次数,d 是一个参数,用来确定循环的限制。这个限制是为了对一个数字数组 [a_1,...,a_n] 进行操作,要求这些数字都是正数,并且它们的总和等于 d。举个例子,如果 n=4,那么它应该做的事情类似于:
for i in range (0,d+1):
for j in range(0,d+1-i):
for k in range(0,d+1-i-j):
doSomething([i, j, k, d-i-j-k])
我从这个问题和我几年前的编程知识中了解到,这个应该用递归函数来实现。不幸的是,我有点搞不清楚应该如何传递参数(我已经有几年没编程了,手生了)。
2 个回答
2
你当然可以使用递归的方法,但你也可以直接用itertools这个库(https://docs.python.org/2/library/itertools.html)来解决问题:
import itertools
def call_on_sum_permutations(callable, n, d):
for a in itertools.product(range(d+1),repeat=n):
if sum(a) == d:
callable(a)
def pr(x):
print(x)
call_on_sum_permutations(pr, 3, 10)
不过如果n很大的话,这种方法可能会变得很复杂。
另外,你的描述提到的是正数a_1到a_n,但你的代码却允许零,所以我也这样做了。你可能还会发现itertools.permutations、itertools.combinations等函数也很有用,可以去看看这个模块里的其他内容。
2
这里有一个递归的解决方案:
def drill(f, n, d, items=()):
if n > 1:
for i in range(d+1):
drill(f, n-1, d-i, items+(i,))
else:
f(list(items) + [d])
... 这样调用:
>>> def p(x): print x
...
>>> drill(p, 3, 4)
[0, 0, 4]
[0, 1, 3]
[0, 2, 2]
[0, 3, 1]
[0, 4, 0]
[1, 0, 3]
[1, 1, 2]
[1, 2, 1]
[1, 3, 0]
[2, 0, 2]
[2, 1, 1]
[2, 2, 0]
[3, 0, 1]
[3, 1, 0]
[4, 0, 0]