def zip_equal(*iterables):
"""
Zip and raise exception if lengths are not equal.
Taken from solution by Martijn Pieters, here:
:param iterables: Iterable objects
:return: A new iterator outputting tuples where one element comes from each iterable
"""
sentinel = object()
for combo in zip_longest(*iterables, fillvalue=sentinel):
if any(sentinel is c for c in combo):
raise ValueError('Iterables have different lengths. Iterable(s) #{} (of 0..{}) ran out first.'.format([i for i, c in enumerate(combo) if c is sentinel], len(combo)-1))
yield combo