是否有相当于多维范围的Python(n)?

在Python中,范围(3)将返回[0,1,2]。 有多维范围的等价物吗?

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

所以,举例来说,尽pipe在基于瓦片的游戏上矩形区域的瓦片可以写成:

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

注意我没有要求执行。 我想知道这是否是一个公认的模式,如果有Python的内置函数或它的标准/通用库。

在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 

你可以使用itertools.product()

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

如果你想把这个扩展到一个十维循环或类似的荒谬的话,那么多重的xrange()语句可以这样expression:

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

其中循环了十个variables,从(0,0,0,0,0,0,0,0,0,0)(2,2,2,2,2,2,2,2,2,2)


一般来说, itertools是一个非常棒的模块。 正则expression式比“简单”string方法expression得多, itertools是expression复杂循环的一种非常优雅的方式。 您应该自己去阅读itertools模块文档。 这将使你的生活更有趣。

这其实有一个简单的语法。 你只需要有两个s:

 >>> [(x,y) for x in range(3) for y in range(2)] [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1)] 

这就是两个名单的笛卡尔积 :

 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) 

您可以使用itertools模块的product

 itertools.product(range(3), range(2)) 

我会看看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)] 

Numpy的ndindex()适用于你给出的例子,但是它不能提供所有的用例。 与Python的内置range() (允许任意startstopstep ,numpy的np.ndindex()只接受stop 。 ( start推定为(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)