在 Python 中使用生成器递归循环向量

Recursivly looping through vectors with generators in Python

以下 python-代码使用递归打印所有长度为 3 且总和为 2 的非负整数列表,它按预期工作:

def rek(f,sum,n,vector=[]): #applies f to all Z^n_+ vectors of sum 'sum'
    if n==1:
        f(vector+[sum])
    else:        
        for i in range(sum+1):
            rek(f,sum-i,n-1,vector+[i])
                   
rek(print,2,3)
Output: 

 [0, 0, 2]  [0, 1, 1]  [0, 2, 0]  [1, 0, 1]  [1, 1, 0]  [2, 0, 0]

我的问题是我是否可以以及如何使用生成器来做到这一点?我希望能够写出类似

的东西
for vector in vector_generator(2,3):
    print(vector)

打印相同的向量。

您应该研究 yieldyield from,这是您的做法:

def vector_generator(sum, n, vector=()):
    if n == 1:
        yield vector + (sum,)
    else:
        for i in range(sum + 1):
            yield from vector_generator(sum - i, n - 1, vector + (i,))

请注意,我将 vector 更改为一个元组,因为将可变对象作为默认参数不是一个好的做法(编辑该值将更改默认参数)。

您可以通过简单的方式将您的函数转换为生成器:

def vector_generator(sum,n,vector=None):
    vector = vector or []
    if n==1:
        yield vector+[sum]
    else:        
        for i in range(sum+1):
            yield from vector_generator(sum-i,n-1,vector+[i])


for vector in vector_generator(2,3):
    print(vector)
def gen(s,n):
    nums = [0 for _ in range(n)]
    while True:
        if sum(nums) == s:
            yield nums.copy()
        cidx = 0
        nums[cidx] += 1
        while nums[cidx] == s+1:
            nums[cidx] = 0
            cidx += 1
            if cidx == n:
                return
            nums[cidx] += 1
    
                   
for vector in gen(2,3):
    print(vector)

不是最佳解决方案,但它应该会给出正确的结果。它所做的基本上是用数字 [0-s] 遍历所有可能的长度 n 的数组,并产生总和为 s.

的数组