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
_______________________________________________
Python-ideas mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/X6FBTVNQPIURKXFUIT4G4SH4G53YUIWD/
Code of Conduct: http://python.org/psf/codeofconduct/