将 itertools 用于具有依赖性的不同范围的任意数量的嵌套循环?
Using itertools for arbitrary number of nested loops of different ranges with dependencies?
给定上限列表:B1、B2、.. BN;
依赖函数:f1, ..., fN-1,
我想知道 python 中是否有使用 itertools 或其他 类 的食谱:
for i1 in range(0, B1):
for i2 in range(f1(i1), B2): ...
for iN in range(fN-1(iN-1), BN)
dostuff(i1, i2, ... iN)
哪里有N层嵌套?
我想像这样使用这个辅助函数:
dependentProducts(Bs, fs, dostuff),
其中 returns 一个列表或可迭代的
理想情况下,实现应该是迭代的而不是递归的。
这是您想要的示例:
B = [10, 15, 20, 5]
F = [lambda x: x,
lambda x: x * x,
lambda x: x * 2 - 5]
def dostuff(i0, i1, i2, i3):
print((i0, i1, i2, i3))
expected = []
for i0 in range(0, B[0]):
for i1 in range(F[0](i0), B[1]):
for i2 in range(F[1](i1), B[2]):
for i3 in range(F[2](i2), B[3]):
expected.append([i0, i1, i2, i3])
我找到了这样的递归解决方案:
def iter_rec(found, fL, bL):
if fL and bL:
ik = found[-1] if found else 0
fk = fL[0]
bk = bL[0]
for i in range(fk(ik), bk):
for item in iter_rec(found + [i], fL[1:], bL[1:]):
yield item
else:
yield found
# prepend the null function to ensure F and B have the same size
F = [lambda x: 0] + F
current = [item for item in iter_rec([], F, B)]
结果相同
assert expected == current
使用@LaurentLAPORTE 设置的迭代解决方案。将这段代码放在他的下面,它应该可以工作。我的 args
是一堆输入 dostuff
的参数,只要它已满。实际解决方案是中间部分,顶部和底部只是测试。
stefan = []
def dostuff(*args):
stefan.append(list(args))
args = [-1]
while args:
n = len(args)
args[-1] += 1
if args[-1] >= B[n-1]:
args.pop()
elif n == len(B):
dostuff(*args)
else:
args.append(F[n](args[-1]) - 1)
assert expected == stefan
给定上限列表:B1、B2、.. BN;
依赖函数:f1, ..., fN-1,
我想知道 python 中是否有使用 itertools 或其他 类 的食谱:
for i1 in range(0, B1):
for i2 in range(f1(i1), B2): ...
for iN in range(fN-1(iN-1), BN)
dostuff(i1, i2, ... iN)
哪里有N层嵌套?
我想像这样使用这个辅助函数:
dependentProducts(Bs, fs, dostuff),
其中 returns 一个列表或可迭代的
理想情况下,实现应该是迭代的而不是递归的。
这是您想要的示例:
B = [10, 15, 20, 5]
F = [lambda x: x,
lambda x: x * x,
lambda x: x * 2 - 5]
def dostuff(i0, i1, i2, i3):
print((i0, i1, i2, i3))
expected = []
for i0 in range(0, B[0]):
for i1 in range(F[0](i0), B[1]):
for i2 in range(F[1](i1), B[2]):
for i3 in range(F[2](i2), B[3]):
expected.append([i0, i1, i2, i3])
我找到了这样的递归解决方案:
def iter_rec(found, fL, bL):
if fL and bL:
ik = found[-1] if found else 0
fk = fL[0]
bk = bL[0]
for i in range(fk(ik), bk):
for item in iter_rec(found + [i], fL[1:], bL[1:]):
yield item
else:
yield found
# prepend the null function to ensure F and B have the same size
F = [lambda x: 0] + F
current = [item for item in iter_rec([], F, B)]
结果相同
assert expected == current
使用@LaurentLAPORTE 设置的迭代解决方案。将这段代码放在他的下面,它应该可以工作。我的 args
是一堆输入 dostuff
的参数,只要它已满。实际解决方案是中间部分,顶部和底部只是测试。
stefan = []
def dostuff(*args):
stefan.append(list(args))
args = [-1]
while args:
n = len(args)
args[-1] += 1
if args[-1] >= B[n-1]:
args.pop()
elif n == len(B):
dostuff(*args)
else:
args.append(F[n](args[-1]) - 1)
assert expected == stefan