40

この問題は、しばらくの間私を悩ませてきました。forPythonでネストされたループを書く簡単な方法はありますか? たとえば、私のコードが次のようになったとします。

  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 つのスペースを使用する代わりにインデントすると、問題が発生する可能性があります。

forああ、例では、物事を簡単にするためにネストされたループが 4 つしかありませんでした。

4

11 に答える 11

59

例のようにデカルト積を頻繁に反復している場合は、Python 2.6 の 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()
于 2009-08-14T23:51:35.923 に答える
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
于 2009-08-14T23:53:34.517 に答える
10

そのようなプログラム ロジックに直面した場合、ループのシーケンスを 2 つ以上の個別の関数に分割するでしょう。

Python のもう 1 つの手法は、ループの代わりに、可能な場合はリスト内包表記を使用することです。

于 2009-08-14T23:36:03.223 に答える
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-)

于 2009-08-14T23:36:59.230 に答える
6

itertools.product技術的には、N シーケンスのデカルト積を取得し、それを反復処理するために使用できます。

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

しかし、それが実際に可読性に関して何かを勝ち取るとは思いません。

于 2009-08-14T23:51:54.503 に答える
3

私の個人的な主張は、ネストされたループが6つある場合、何か間違ったことをしている可能性が高いということです...

とはいえ、機能分解はあなたが探しているものです。一部のループが別の関数呼び出しで発生するようにリファクタリングしてから、それらの関数を呼び出します。

于 2009-08-14T23:36:32.083 に答える
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 回呼び出されます。つまり、可能なポイントの組み合わせごとに 1 回呼び出されます。

于 2009-08-14T23:57:37.737 に答える
2

リスト内包表記を調べましたか?

何かのようなもの:

[do_something() for x in range(3) for y in range(3)]
于 2009-08-14T23:37:05.187 に答える
2

その方法はかなり簡単で簡単に見えます。ループの複数のレイヤーに一般化したいと言っているのですか....実際の例を挙げていただけますか?

私が考えることができる別のオプションは、関数を使用してパラメーターを生成し、それらをループで適用することです

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

for x,y in generate_params(3):
    do_something()
于 2009-08-14T23:37:45.407 に答える
1

map() 関数を使用することもできます

于 2009-08-14T23:47:07.477 に答える