Skip to content

Instantly share code, notes, and snippets.

@jtdevos
Created April 12, 2018 18:23
Show Gist options
  • Save jtdevos/96ea4739b7b185e4d5121a896ae7a48a to your computer and use it in GitHub Desktop.
Save jtdevos/96ea4739b7b185e4d5121a896ae7a48a to your computer and use it in GitHub Desktop.
comparing two sorted DBAPI rowsets in python
SOURCE_LEFT, SOURCE_RIGHT, SOURCE_BOTH = 'left', 'right', 'both'
def comm(itera, iterb, cmpfunc=None):
""" merge two iterators and indicate which items are common (similar
to the unix 'comm' command).
Return an iterator containing deduped union of two sorted iterables and
a string indicating whether merged values are unique to the 'left' iterator,
'right' iterator or if they are common to both iterators.
itera -- the 'left' iterable
iterb -- the 'right' iterable
cmpfunc -- Optional comparator. If none supplied, use natural order.
"""
cmp = cmpfunc or (lambda a,b: (a > b) - (a < b))
done = object()
anext = next(itera, done)
bnext = next(iterb, done)
while (anext is not done) or (bnext is not done):
if bnext is done or (anext is not done and cmp(anext, bnext) < 0):
# left column entry is unique
yield anext, SOURCE_LEFT
anext = next(itera, done)
elif anext is done or (bnext is not done and cmp(anext, bnext) > 0):
# right column entry is unique
yield bnext, SOURCE_RIGHT
bnext = next(iterb, done)
else:
if bnext is not done and anext is not done and cmp(anext, bnext) == 0:
# value is common to both iterators
yield bnext, SOURCE_BOTH
anext = next(itera, done)
bnext = next(iterb, done)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment