0

我将此代码与一些实际编码一起使用,这些编码需要封闭循环中的所有变量。我在想,如果必须进行迭代的范围相同,则必须有另一种缩进更少且对所有变量具有相同访问权限的方法。

有没有替代这种嵌套循环的方法

  • 缩进更少
  • 在封闭范围内以相同的顺序访问变量

编码:

import itertools
import time

#My Way
s = time.time()
sums_pyramid = [0] * 36
for i in xrange(1,5):
    for j in xrange(1,5):
        for k in xrange(1,5):
            for l in xrange(1,5):
                for m in xrange(1,5):
                    for n in xrange(1,5):
                        for o in xrange(1,5):
                            for p in xrange(1,5):
                                for q in xrange(1,5):
                                    sums_pyramid[i+j+k+l+m+n+o+p+q - 1] += 1
print (time.time() - s)


#Lattyware's suggested way
s = time.time()
sums_pyramid = [0] * 36
for i,j,k,l,m,n,o,p,q in itertools.product(xrange(1,5), repeat = 9):
    sums_pyramid[i+j+k+l+m+n+o+p+q - 1] += 1
print (time.time() - s)

计时结果

#My way
0.259999990463
#Lattyware's suggested way
0.310000181198

编辑2:

在 Lattyware 建议time我应该使用timeit模块而不是使用模块之后,我得到了这些结果

新代码:

import itertools

def p():
    #My Way
    sums_pyramid = [0] * 36
    for i in xrange(1,5):
        for j in xrange(1,5):
            for k in xrange(1,5):
                for l in xrange(1,5):
                    for m in xrange(1,5):
                        for n in xrange(1,5):
                            for o in xrange(1,5):
                                for p in xrange(1,5):
                                    for q in xrange(1,5):
                                        sums_pyramid[i+j+k+l+m+n+o+p+q - 1] += 1


def q():
    #Lattyware's suggested way
    sums_pyramid = [0] * 36
    for i,j,k,l,m,n,o,p,q in itertools.product(xrange(1,5), repeat = 9):
        sums_pyramid[i+j+k+l+m+n+o+p+q - 1] += 1

if __name__ == '__main__':
    times = 10
    from timeit import Timer
    print Timer(p, 'gc.enable()').timeit(number = times)

    print Timer(q, 'gc.enable()').timeit(number = times)

新时间:

1.60324387493
1.28266455309

这些表明 Lattyware 的代码更好。

4

1 回答 1

6

假设(如在您的示例中)循环都独立于父循环,您想要itertools.product().

import itertools

for i, j, k, l, m, n, o, p, q in itertools.product(xrange(1, 5), repeat=9):
    ...

在这里,我使用repeat关键字参数作为简写,就像在您的示例中一样,迭代器都是相同的,但是如果您的迭代器不完全相同,您也可以将多个迭代器传递给它。

它也将比许多嵌套循环更有效。请注意,您的问题可能有更好的解决方案 - 因为使用如此多的嵌套循环进行迭代可能是大量的迭代,因此非常慢。

或者,如果您的循环依赖于它们的父循环等(product()因此不合适),您可以定义函数来提取一些繁重的嵌套并将其抽象出来。

for i in xrange(1,5):
    for j in xrange(1,5):
        for k in xrange(1,5):
            for l in xrange(1,5):
                for m in xrange(1,5):
                    inner_loops(i, j, k, l, m)

def inner_loops(i, j, k, l, m):
    for n in xrange(1,5):
        for o in xrange(1,5):
            for p in xrange(1,5):
                for q in xrange(1,5):
                    pass

这将比 执行得更差product(),并且可读性较差,但可能是必要的,具体取决于情况。当然,您可以在需要的地方使用尽可能多的函数来尽可能多地减少嵌套。

最后一点,我假设您使用范围作为一个简单的示例,但是如果您打算使用索引循环数据结构,请不要!它很难阅读,不灵活且缓慢。直接循环数据结构本身——这些方法可以正常工作(事实上,更好)。

于 2013-06-28T10:02:25.123 回答