Last active
August 29, 2015 14:08
-
-
Save davepeck/017b15f10351f85f3428 to your computer and use it in GitHub Desktop.
Random python iteration toy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def interleave(iterables, cmp=None, key=None, reverse=False): | |
""" | |
Given a collection of iterables, walk through them in | |
parallel, at each step yielding the current value | |
that comes first in the sort order, and advancing | |
that single iterator. | |
If each iterable is already sorted, this will produce | |
a total ordering. If not, it produces a 'greedy' ordering | |
>>> list(interleave([[1,2],[3,4]])) | |
[1,2,3,4] | |
>>> list(interleave([[1,2],[0,3]])) | |
[0,1,2,3] | |
>>> list(interleave([[1,2],[-1,-2]])) | |
[-1, -2, 1, 2] | |
""" | |
def _advance(iterator): | |
# I've never been happy with Python's | |
# use of exceptions for iteration | |
# control flow. Dangit. | |
try: | |
return (iterator.next(), False) | |
except StopIteration: | |
return (None, True) | |
# This code could certainly be more efficient, | |
# for example by maintaining a sorted array | |
# of current values and modifying it in place | |
# (probably using bisect); but is there a way | |
# to compress it more? | |
iterators = map(lambda i: i.__iter__(), iterables) | |
states = map(lambda i: [i, _advance(i)], iterators) # Each state is [iterator, (current_value, is_stopped)] | |
exhausted = reduce(lambda exhausted, state: exhausted and state[1][1], states, True) | |
while not exhausted: | |
available_states = filter(lambda state: not state[1][1], states) | |
sorted_states = sorted(available_states, cmp=cmp, key=lambda state: key(state[1][0]) if key else state[1][0], reverse=reverse) | |
chosen_state = sorted_states[0] | |
yield chosen_state[1][0] | |
chosen_state[1] = _advance(chosen_state[0]) | |
exhausted = reduce(lambda exhausted, state: exhausted and state[1][1], states, True) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment