Skip to content

Instantly share code, notes, and snippets.

@amcgregor
Last active December 4, 2020 14:36
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 amcgregor/e0f9d4f08f45959c23da88da0a381139 to your computer and use it in GitHub Desktop.
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.
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
@amcgregor
Copy link
Author

amcgregor commented Dec 3, 2020

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment