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.

Leave a Reply

Your email address will not be published. Required fields are marked *

Warning: This site uses Akismet to filter spam. Until or unless I can find a suitable replacement anti-spam solution, this means that (per their indemnification document) all commenters' IP addresses will be sent to Automattic, Inc., who may choose to share such with 3rd parties.
If this is unacceptable to you, I highly recommend using an anonymous proxy or public Wi-Fi connection when commenting.