""" >>> list(zip_exc([])) [] >>> list(zip_exc((), (), ())) [] >>> list(zip_exc("abc", range(3))) [('a', 0), ('b', 1), ('c', 2)] >>> try: ... list(zip_exc("", range(3))) ... except LengthMismatch: ... print "mismatch" mismatch >>> try: ... list(zip_exc(range(3), ())) ... except LengthMismatch: ... print "mismatch" mismatch >>> try: ... list(zip_exc(range(3), range(2), range(4))) ... except LengthMismatch: ... print "mismatch" mismatch >>> items = zip_exc(range(3), range(2), range(4)) >>> items.next() (0, 0, 0) >>> items.next() (1, 1, 1) >>> try: items.next() ... except LengthMismatch: print "mismatch" mismatch """ from itertools import chain, izip class LengthMismatch(Exception): pass def _throw(): raise LengthMismatch yield None # unreachable def _check(rest): for i in rest: try: i.next() except LengthMismatch: pass else: raise LengthMismatch return yield None # unreachable def zip_exc(*iterables): """Like itertools.izip(), but throws a LengthMismatch exception if the iterables' lengths differ. """ rest = [chain(i, _throw()) for i in iterables[1:]] first = chain(iterables[0], _check(rest)) return izip(*[first] + rest) if __name__ == "__main__": import doctest doctest.testmod()