Skip to content

Instantly share code, notes, and snippets.

@mahmoud
Last active August 29, 2015 14:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mahmoud/30fecefcb9a308573f92 to your computer and use it in GitHub Desktop.
Save mahmoud/30fecefcb9a308573f92 to your computer and use it in GitHub Desktop.
def close_range(start, step=1, count=None):
i, orig_step = 0, step
if count is None:
count = start / step
while i < count:
yield start + (i * step)
step *= -1
if step != orig_step:
i += 1
return
print list(close_range(5))
[5, 4, 6, 3, 7, 2, 8, 1, 9]
def iter_nearest(seq, idx, step=1, count=None):
"""
>>> list(iter_nearest(range(10), 3))
[3, 4, 2, 5, 1, 6, 0, 7, 8, 9]
>>> list(iter_nearest(range(10), 3, count=5))
[3, 4, 2, 5, 1]
>>> list(iter_nearest(range(10), 3, step=-1))
[3, 2, 4, 1, 5, 0, 6, 7, 8, 9]
>>> list(iter_nearest(range(10), 3, step=-2))
[3, 2, 5, 0, 7, 9]
>>> list(iter_nearest(range(10), 3, count=0))
[]
>>> list(iter_nearest(range(0), 3, count=5))
[]
>>> list(iter_nearest(range(10), 100))
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
"""
if count is None:
count = len(seq)
abs_step, len_seq = abs(step), len(seq)
if step > 0:
before = xrange(min(idx, len_seq - 1), -1, -abs_step)
after = xrange(max(0, idx + 1), len_seq, abs_step)
izipper = izip_longest(before, after)
else:
before = xrange(min(idx - 1, len_seq - 1), -1, -abs_step)
after = xrange(max(0, idx), len_seq, abs_step)
izipper = izip_longest(after, before)
gen = (v for pair in izipper for v in pair if v is not None)
i = 0
while i < count:
yield seq[next(gen)]
i += 1
return
def iter_probe(len_seq, idx, step=1, count=None):
"""Probe sequence indices up to but not including *len_seq* based on
proximity to target index *idx*, according to *step* (1 goes up
first, the default, whereas -1 down first), yielding a maximum of
*count* indices. Yields only integers >= 0.
>>> list(iter_nearest(range(10), 3))
[3, 4, 2, 5, 1, 6, 0, 7, 8, 9]
>>> list(iter_nearest(range(10), 3, count=5))
[3, 4, 2, 5, 1]
>>> list(iter_nearest(range(10), 3, step=-1))
[3, 2, 4, 1, 5, 0, 6, 7, 8, 9]
>>> list(iter_nearest(range(10), 3, step=-2))
[3, 2, 5, 0, 7, 9]
>>> list(iter_nearest(range(10), 3, count=0))
[]
>>> list(iter_nearest(range(0), 3, count=5))
[]
>>> list(iter_nearest(range(10), 100))
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
"""
if count is None:
count = len_seq
abs_step = abs(step)
if step > 0:
before = xrange(min(idx, len_seq - 1), -1, -abs_step)
after = xrange(max(0, idx + 1), len_seq, abs_step)
izipper = izip_longest(before, after)
else:
before = xrange(min(idx - 1, len_seq - 1), -1, -abs_step)
after = xrange(max(0, idx), len_seq, abs_step)
izipper = izip_longest(after, before)
gen = (v for pair in izipper for v in pair if v is not None)
i = 0
while i < count:
yield next(gen)
i += 1
return
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment