Even sized hexagonal grid generator for python
I am trying to do "even only" a hex grid in Python.
Expected Result:
[[(0,0), (2,0), (4,0), (6,0)],
[(1,1), (3,1), (5,1), (7,1)],
[(0,2), (2,2), (4,2), (6,2)],
[(1,3), (3,3), (5,3), (7,3)]]
I've been doing this:
>>> [[(x,y) for x in range(7)[::2]] for y in range(4)]
[[(0,0), (2,0), (4,0), (6,0)],
[(0,1), (2,1), (4,1), (6,1)],
[(0,2), (2,2), (4,2), (6,2)],
[(0,3), (2,3), (4,3), (6,3)]]
But the next place I went to throws an exception:
>>> [[(x,y) for x in xrange(y % 2, 6 + (y % 2))[::2]] for y in range(4)]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: sequence index must be integer, not 'slice'
source to share
Another way to do it:
[zip(range(i % 2, 8, 2), (i,) * 4) for i in range(4)]
Switching range
for xrange
in this piece of code will not break it. Using the optional step argument is range
better than getting the full range and slicing it up.
Explanation why xrange failed:
In Python 2.x, calls xrange
return a special type of xrange object, and calls range
return regular Python lists:
>>> xrange(10)
xrange(10)
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Version error xrange
because you cannot use slice syntax with objects xrange
:
>>> xrange(10)[::2]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: sequence index must be integer, not 'slice'
But you can do it with range
, since it range
returns a list that supports more operations:
>>> range(10)[::2]
[0, 2, 4, 6, 8]
However, instead of slicing the returned list out of the range with a stride, I would recommend just using the optional stride argument, which will work on both range and xrange!
source to share
On posting the question, I developed a generator that I wanted:
>>> [[(x,y) for x in range(8)[y % 2::2]] for y in range(4)]
[[(0,0), (2,0), (4,0), (6,0)],
[(1,1), (3,1), (5,1), (7,1)],
[(0,2), (2,2), (4,2), (6,2)],
[(1,3), (3,3), (5,3), (7,3)]]
However, I don't know why the version is failing xrange
.
source to share