Just found out about this cool feature in the Python standard library that allows you to merge two iterables based on a comparison:
from heapq import merge as merge_heapwise
some_numbers = (1, 5, 10, 15)
other_numbers = (2, 4, 6, 8, 10, 12, 14, 16)
merged_numbers = tuple(merge_heapwise(some_numbers, other_numbers))  # Using a tuple so comparisons work, for didactic demo reasons
assert merged_numbers == (1, 2, 4, 5, 6, 8, 10, 12, 14, 15, 16)
It's lazy, so you can use it for merging unbounded streams, though beware it could be considered "slightly destructive": it'll be internally "hoarding" 1 item from each iterable it didn't yield from that iteration (obviously, this is necessarily a part of the design, since it's got to have both items before it can compare them.) It supports an arbitrary number of input iterables.
It supports parameter key, so you can specify some pre-comparison interpretation of the elements you're merging (such as key=lambda e: float(e.get('x')), which I just recently used to merge two streams of SVG element generators into a reasonable order for rendering.)
It isn't really fully general; unless you wanted to make a wrapper class overriding the behavior of the comparison operators, you can't use an arbitrary function for deciding which element this function yields; however, for my use-case, it was pretty handy to have this function pre-written in the standard library.