在 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)
打印相同的向量。
您应该研究 yield
和 yield 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
.
的数组
以下 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)
打印相同的向量。
您应该研究 yield
和 yield 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
.