在python中有一种更简单的方法来编写6个嵌套for循环吗?

时间:2009-08-14 23:31:41

标签: python for-loop nested-loops

这个问题现在已经有一段时间了。有没有更简单的方法在python中编写嵌套的for循环?例如,如果我的代码是这样的:

  for y in range(3):
    for x in range(3):
      do_something()
      for y1 in range(3):
        for x1 in range(3):
          do_something_else()

会有更简单的方法吗?我知道这段代码有效但是当你缩进而不是像我一样使用2个空格时,它可能会成为一个问题。

在示例中,只有4个嵌套for循环使事情变得更容易。

11 个答案:

答案 0 :(得分:57)

如果您经常在示例中迭代笛卡尔积,那么您可能需要调查Python 2.6's itertools.product - 或者如果您使用的是早期的Python,请编写自己的。

from itertools import product
for y, x in product(range(3), repeat=2):
  do_something()
  for y1, x1 in product(range(3), repeat=2):
    do_something_else()

答案 1 :(得分:14)

这在循环多维空间时相当常见。我的解决方案是:

xy_grid = [(x, y) for x in range(3) for y in range(3)]

for x, y in xy_grid:
    # do something
    for x1, y1 in xy_grid:
        # do something else

答案 2 :(得分:10)

当面对那种程序逻辑时,我可能会将循环序列分解为两个或多个单独的函数。

Python中的另一项技术是尽可能使用list comprehensions,而不是循环。

答案 3 :(得分:8)

假设每个循环都有某种独立的含义,请将它们分解为命名函数:

def do_tigers():
    for x in range(3):
        print something

def do_lions():
    do_lionesses()
    for x in range(3):
        do_tigers()

def do_penguins():
    for x in range(3):
        do_lions()

..etc.

我或许可以选择更好的名字。 8 - )

答案 4 :(得分:5)

从技术上讲,您可以使用itertools.product获取N个序列的笛卡尔积,并迭代:

 for y, x, y1, x1 in itertools.product(range(3), repeat=4):
   do_something_else()

但我不认为这实际上会赢得任何可读性。

答案 5 :(得分:4)

Python迭代器,特别是生成器,完全存在,以便能够很好地重构其他复杂的循环。当然,很难从一个简单的例子中得到一个抽象,但假设3需要是一个参数(也许整个range(3)应该是?),以及你要调用的两个函数需要一些循环变量参数,你可以重构代码:

  for y in range(3):
    for x in range(3):
      do_something(x, y)
      for y1 in range(3):
        for x1 in range(3):
          do_something_else(x, y, x1, y1)

进入,例如:

def nestloop(n, *funcs):
  head = funcs[0]
  tail = funcs[1:]
  for y in range(n):
    for x in range(n):
      yield head, x, y
      if tail:
        for subtup in nestloop(n, *tail):
           yield subtup[:1] + (x, y) + subtup[1:]

for funcandargs in nestloop(3, do_something, do_something_else):
  funcandargs[0](*funcandargs[1:])

确切的重构类型无疑需要根据您的确切目的进行调整,但一般来说迭代器(通常实际上只是简单的生成器)可以提供非常好的循环重构 - 所有循环逻辑都在内部生成器,应用程序级代码留下简单的for循环和for循环中产生的项目的实际应用程序相关处理。

答案 6 :(得分:3)

我个人的观点是,如果你有6个嵌套循环,你可能会做错事......

那就是说,功能分解是你正在寻找的。重构所以一些循环发生在单独的函数调用中,然后调用这些函数。

答案 7 :(得分:3)

从您的代码中看起来您希望对x和y在0..2范围内的每一对可能的点执行操作。

要做到这一点:

for x1,y1,x2,y2 in itertools.product(range(3), repeat=4):
    do_something_with_two_points(x1,y1,2,y2)

操作do_something_with_two_points将被调用81次 - 每次可能的点组合一次。

答案 8 :(得分:2)

您是否查看了List Comprehensions?

类似的东西:

[do_something() for x in range(3) for y in range(3)]

答案 9 :(得分:2)

这种方式看起来非常简单易行。你是说你想要推广到多层循环......你能给出一个真实的例子吗?

我能想到的另一个选择是使用函数生成参数,然后将它们应用于循环中

def generate_params(n):
    return itertools.product(range(n), range(n))

for x,y in generate_params(3):
    do_something()

答案 10 :(得分:2)

您还可以使用map() function