Search code examples
pythonhexagonal-tiles

Even-only hexagonal grid generator for python


I'm trying to make an "even only" hex grid in Python.

The expected output is

[[(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 was tinkering with 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 from there 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'

Solution

  • Another way of doing it is the following:

    [zip(range(i % 2, 8, 2), (i,) * 4) for i in range(4)]
    

    Swapping out range for xrange in this code snippet will not break it. Using the optional step argument on range is better than getting a full range and slicing it.


    Explanation of why slicing xrange failed:

    In Python 2.x, calls toxrange return a special type of xrange object, while calls to range return ordinary Python lists:

    >>> xrange(10)
    xrange(10)
    >>> range(10)
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    

    The xrange version crashed because you can't use slice-syntax with the xrange objects:

    >>> 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 range returns a list which supports more operations:

    >>> range(10)[::2]
    [0, 2, 4, 6, 8]
    

    Still, rather than slicing the returned list from range with a step, I would recommend just using the optional step argument that will work with both range and xrange!