Right out of the box, zip() is hardwired to dispose of the unmatched item. So, you need a way to remember values before they get consumed.
The itertool called tee() was designed for this purpose. You can use it to create a “shadow” of the first input iterator. If the second iterator terminates, you can fetch first iterator’s value from the shadow iterator.
Here’s one way to do it that uses existing tooling, that runs at C-speed, and that is memory efficient:
>>> from itertools import tee
>>> from operator import itemgetter
>>> iterable1, iterable2 = 'abcde', 'xyz'
>>> it1, shadow1 = tee(iterable1)
>>> it2 = iter(iterable2)
>>> combined = map(itemgetter(0, 1), zip(it1, it2, shadow1))
>>> list(combined)
[('a', 'x'), ('b', 'y'), ('c', 'z')]
>>> next(shadow1)
'd'