Skip to content

Instantly share code, notes, and snippets.

@craigds
Created April 14, 2021 23:29
Show Gist options
  • Save craigds/d93a2da26c34da51ee854c2093ea54ef to your computer and use it in GitHub Desktop.
Save craigds/d93a2da26c34da51ee854c2093ea54ef to your computer and use it in GitHub Desktop.
def diff_iterators(iter1, iter2):
"""
Yields every value that differs between two iterators, assuming they're ordered the same.
ie, given
iter1 = iter([1, 2, 5, 7, 9, 10, 12])
iter2 = iter([1, 3, 4, 5, 6, 9, 11])
yields:
2, 3, 4, 6, 7, 10, 11, 12
"""
try:
blob1 = next(iter1)
except StopIteration:
# finished iter1? the rest of iter2 is a diff
yield from iter2
return
try:
blob2 = next(iter2)
except StopIteration:
# finished iter2? the rest of iter1 is a diff, including blob1 we just read
yield blob1
yield from iter1
return
while True:
try:
# yield from iter1 until we get an item that's >= blob2
while blob1 < blob2:
yield blob1
blob1 = next(iter1)
except StopIteration:
# finished iter1? the rest of iter2 is a diff, including blob2 we just read
yield blob2
yield from iter2
return
try:
while blob2 < blob1:
yield blob2
blob2 = next(iter2)
except StopIteration:
# finished iter2? the rest of iter1 is a diff, including blob1 we just read
yield blob1
yield from iter1
return
if blob1 == blob2:
# since these blobs are the same, advance both iterators to the next item.
try:
blob1 = next(iter1)
except StopIteration:
# finished iter1? the rest of iter2 is a diff
yield from iter2
return
try:
blob2 = next(iter2)
except StopIteration:
# finished iter2? the rest of iter1 is a diff, including blob1 we just read
yield blob1
yield from iter1
return
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment