Python Forum

Full Version: Cute oscillating range generation snippet I saw on irc
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Iterating both up and down from the middle of a range, with only the range max value input:

import itertools
def spiral(n):
    r1 = range(n // 2, n)
    r2 = range(n // 2 - 1, -1, -1)
    for a, b in itertools.zip_longest(r1, r2):
        yield a
        if b is not None:
            yield b
   
And some application:

list(spiral(6))
[3, 2, 4, 1, 5, 0]
In python 3, range() has a lot of extra features that weren't available in 2.x, such as indexing and slicing. It's fast, even on large ranges, as it computes the values when indexed, instead of iterating over the range.

So another, probably worse, way of doing it, could be like so:
>>> def spiral(size):
...   spinner = range(size)
...   right = len(spinner) // 2
...   left = right - 1
...   exhaused = False
...   while not exhaused:
...     exhaused = True
...     if right < len(spinner):
...       yield spinner[right]
...       right += 1
...       exhaused = False
...     if left >= 0:
...       yield spinner[left]
...       left -= 1
...       exhaused = False
...
>>> list(spiral(6))
[3, 2, 4, 1, 5, 0]