56

Pythonでは、range(3)は[0,1,2]を返します。多次元範囲に相当するものはありますか?

range((3,2)) # [(0,0),(0,1),(1,0),(1,1),(2,0),(2,1)]

したがって、たとえば、タイルベースのゲームで長方形の領域のタイルをループすることは、次のように記述できます。

for x,y in range((3,2)):

私は実装を求めていないことに注意してください。これが認識されたパターンであるかどうか、Pythonに組み込み関数があるのか​​、それとも標準/共通ライブラリであるのかを知りたいです。

4

7 に答える 7

75

numpyでは、それはnumpy.ndindexです。もご覧くださいnumpy.ndenumerate

例えば

import numpy as np
for x, y in np.ndindex((3,2)):
    print(x, y)

これにより、次のようになります。

0 0
0 1
1 0
1 1
2 0
2 1
于 2012-04-11T00:03:12.087 に答える
39

あなたが使用することができますitertools.product()

>>> import itertools
>>> for (i,j,k) in itertools.product(xrange(3),xrange(3),xrange(3)):
...     print i,j,k

xrange()これを10次元のループまたは同様にばかげたものにスケールアップしたい場合は、複数の繰り返されるステートメントをそのように表現できます。

>>> for combination in itertools.product( xrange(3), repeat=10 ):
...     print combination

(0,0,0,0,0,0,0,0,0,0)からまで変化する10個の変数をループします(2,2,2,2,2,2,2,2,2,2)


一般的itertoolsに、めちゃくちゃ素晴らしいモジュールです。同様に、正規表現は「プレーンな」文字列メソッドよりもはるかに表現力がitertoolsあり、複雑なループを表現する非常に洗練された方法です。モジュールのドキュメントを読むのはあなた自身の責任です。itertoolsそれはあなたの人生をより楽しくするでしょう。

于 2012-04-10T17:18:08.020 に答える
25

これには実際には簡単な構文があります。必要なforのは2つだけです。

>>> [(x,y) for x in range(3) for y in range(2)]
[(0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1)]
于 2012-04-10T17:17:56.527 に答える
8

したがって、これは2つのリストのデカルト積です。

import itertools
for element in itertools.product(range(3),range(2)):
    print element

この出力を与えます:

(0, 0)
(0, 1)
(1, 0)
(1, 1)
(2, 0)
(2, 1)
于 2012-04-10T17:19:40.423 に答える
4

productモジュールから使用できitertoolsます。

itertools.product(range(3), range(2))
于 2012-04-10T17:18:47.713 に答える
3

私は見ていきますnumpy.meshgrid

http://docs.scipy.org/doc/numpy-1.6.0/reference/generated/numpy.meshgrid.html

これにより、メッシュ/グリッドの各位置でのXグリッド値とYグリッド値が得られます。次に、次のようなことを行うことができます。

import numpy as np
X,Y = np.meshgrid(xrange(3),xrange(2))
zip(X.ravel(),Y.ravel()) 
#[(0, 0), (1, 0), (2, 0), (0, 1), (1, 1), (2, 1)]

また

zip(X.ravel(order='F'),Y.ravel(order='F')) 
# [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1)]
于 2012-04-10T18:57:39.923 に答える
1

Numpyndindex()はあなたが挙げた例で機能しますが、すべてのユースケースに対応しているわけではありません。任意の、、、およびrange()の両方を許可するPythonの組み込みとは異なり、numpyは。のみを受け入れます。(はであると推定され、はです。)startstopstepnp.ndindex()stopstart(0,0,...)step(1,1,...)

これは、組み込みrange()関数のように機能する実装です。つまり、任意の//引数を許可startしますが、単なる整数ではなくタプルで機能stopしますstep

import sys
from itertools import product, starmap

# Python 2/3 compatibility
if sys.version_info.major < 3:
    from itertools import izip
else:
    izip = zip
    xrange = range

def ndrange(start, stop=None, step=None):
    if stop is None:
        stop = start
        start = (0,)*len(stop)

    if step is None:
        step = (1,)*len(stop)

    assert len(start) == len(stop) == len(step)

    for index in product(*starmap(xrange, izip(start, stop, step))):
        yield index

例:

In [7]: for index in ndrange((1,2,3), (10,20,30), step=(5,10,15)):
   ...:     print(index)
   ...:
(1, 2, 3)
(1, 2, 18)
(1, 12, 3)
(1, 12, 18)
(6, 2, 3)
(6, 2, 18)
(6, 12, 3)
(6, 12, 18)
于 2017-09-20T22:57:22.423 に答える