Created
May 10, 2023 00:42
-
-
Save polynomialherder/9bce8338d86fa2c2a3f372217a10bba5 to your computer and use it in GitHub Desktop.
A function that, given a fixed (constant) alternating value and an iterable, constructs a generator that alternately yields the next generator value, or the constant alternating value
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
import itertools | |
def exhausted(generator): | |
try: | |
next(generator) | |
return False | |
except StopIteration: | |
return True | |
def alternate_with(iterable, alternating_value=0, trailing=False): | |
""" Given a fixed (constant) alternating value and an iterable, construct a generator | |
that alternately yields the next generator value, or the constant alternating value | |
Note that iterable might be infinite or very long, so this function should return | |
a generator. If iterable is finite, and we should trail with the alternating value | |
after yielding the last element of iterable, then pass trailing=True. | |
>>> [x for x in alternate_with([1, 2, 3, 4], trailing=False)] | |
[1, 0, 2, 0, 3, 0, 4] | |
>>> [x for x in alternate_with([1, 2, 3, 4], trailing=True)] | |
[1, 0, 2, 0, 3, 0, 4, 0] | |
>>> [x for x in alternate_with("abcd", alternating_value="hello")] | |
['a', 'hello', 'b', 'hello', 'c', 'hello', 'd'] | |
""" | |
# We tee the generator, i.e. create another copy. We'll use the second | |
# copy to peek at the next element to check that the first isn't exhausted | |
# We need this so that we know whether to exit the loop or to return a trailing zero | |
generator_main, generator_check = itertools.tee(iterable, 2) | |
# We want to (safely) advance the cursor in the copy of the main generator so that | |
# it's one step ahead of the main generator -- that way we can use it for peeking | |
exhausted(generator_check) | |
for next_value in generator_main: | |
yield next_value | |
is_exhausted = exhausted(generator_check) | |
if is_exhausted and not trailing: | |
break | |
yield alternating_value |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment