5

给定一个上限列表:B1, B2, .. BN;
依赖函数:f1, ..., fN-1,

我想知道是否有使用 itertools 或 python 中其他类的配方:

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)
它返回一个列表或可迭代的

理想情况下,实现将是迭代的而不是递归的。

4

2 回答 2

3

使用@LaurentLAPORTE 设置的迭代解决方案。将此代码放在他的下面,它应该可以工作。Myargs是一堆参数,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
于 2016-08-23T21:56:34.633 回答
2

这是您想要的示例:

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
于 2016-08-23T20:28:39.613 回答