是否有相当于多维范围的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()
(允许任意start
, stop
和step
,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)