On Sun, May 03, 2020 at 11:13:58PM -0400, David Mertz wrote:
It seems to me that a Python implementation of zip_equals() shouldn't do the check in a loop like a version shows (I guess from more-itertools). More obvious is the following, and this has only a small constant speed penalty.
def zip_equal(*its): yield from zip(*its) if any(_sentinel == next(o, _sentinel) for o in its): raise ZipLengthError
Alas, that doesn't work, even with your correction of `any` to `not all`. py> list(zip_equal("abc", "xy")) [('a', 'x'), ('b', 'y')] The problem here is that zip consumes the "c" from the first iterator, exhausting it, so your check at the end finds that all the iterators are exhausted. Here's the function I used: def zip_equal(*its): _sentinel = object its = tuple(map(iter, its)) yield from zip(*its) if not all(_sentinel == next(o, _sentinel) for o in its): raise RuntimeError
I still like zip_strict() better as a name, but whatever. And I don't care what the exception is, or what the sentinel is called.
The sentinel is a local variable (or at least it ought to be -- there is no need to make it a global. -- Steven