Last active
December 4, 2020 14:36
-
-
Save amcgregor/e0f9d4f08f45959c23da88da0a381139 to your computer and use it in GitHub Desktop.
Consume multiple iterators, filling each when exhausted with the last value they produced.
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
from itertools import repeat | |
def zip_longest_repeating(*iterables): | |
"""Consume multiple iterables, filling each when exhausted with the last value they produced, until all are exhausted.""" | |
tracking = {} # Track the last value seen for each iterable passed in. | |
iterators = [iter(it) for it in iterables] | |
count = len(iterators) | |
if not count: return | |
while True: | |
values = [] | |
for i, it in enumerate(iterators): | |
try: | |
tracking[it] = next(it) | |
except StopIteration: | |
count -= 1 | |
if not count: return | |
iterators[i] = repeat(tracking[it]) | |
values.append(tracking[it]) | |
yield tuple(values) | |
# Vs. https://gist.github.com/rendarz/cc2c99cdce4dc56d2f17e74342bfb241 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Didn't initially see a point in
zip_longest_repeating
a single iterable, but there's no reason why not, thus the revision. No need to exclude programmatic use where the argument list is generated, and may be incidentally singular. Also terminology use.