I'd like to combine two iterators and yield the value(s) of the iterator that has the highest timestamp.
Minimal example and expectations:
# Outputs of these generators are "timestamps"
def gen_even():
for x in range(0, 11, 2):
yield x
def gen_odd():
for x in sorted(list(range(1, 15, 2)) + [6]):
yield x
Combining these two should result in in the following sequence
[0, 1, 2, 3, 4, 5, (6, 6), 7, 8, 9, 10, 11, 13]
I tried the following which runs into StopIteration
after gen1 has been consumed.
gen1 = gen_even()
gen2 = gen_odd()
def gen_both(gen1, gen2):
first = next(gen1)
second = next(gen2)
while True:
if first < second:
yield first
first = next(gen1)
elif first == second:
yield first, second
first = next(gen1)
second = next(gen2)
else:
yield second
second = next(gen2)
gen = gen_both(gen1, gen2)
for i in gen:
print(i)
Output:
0
1
2
3
4
5
(6, 6)
7
8
9
10
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
Cell In[8], line 11, in gen_both(gen1, gen2)
10 yield first
---> 11 first = next(gen1)
12 elif first == second:
StopIteration:
The above exception was the direct cause of the following exception:
RuntimeError Traceback (most recent call last)
Cell In[8], line 21
18 second = next(gen2)
20 gen = gen_both(gen1, gen2)
---> 21 for i in gen:
22 print(i)
RuntimeError: generator raised StopIteration
How can I do this in Python?
You could avoid the stop iterator by handling it as follows:
def gen_both(gen1, gen2):
first = next(gen1, None)
second = next(gen2, None)
while True:
if first is None and second is None:
break
elif first is None:
yield second
second = next(gen2, None)
elif second is None:
yield first
first = next(gen1, None)
else:
if first < second:
yield first
first = next(gen1, None)
elif first == second:
yield first, second
first = next(gen1, None)
second = next(gen2, None)
else:
yield second
second = next(gen2, None)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With