> Since this is not a rare assumption for you, then you should have no trouble
> coming up with some concrete examples of how and when you would use it.
Well, my use cases are "anytime the iterables should be the same length", which
several on this thread have agreed is easily the majority of the time they use
`zip`. So coming up with examples is more like being asked "When do you use
`zip` with what should be equal-length iterables?", or "When do you use the
`int` constructor with its default `base=10`?", or "When do you want the RHS
values of a `dict.__ior__` to overwrite the LHS on conflicting keys?". Uh...
most of the time I use each of those functions? :)
As I've said several times, zip's default behavior is a Good Thing, but
silently omitting data is a big part of that, and its dangerous enough that I
think a straightforward check for "valid" input would be very, very valuable.
I understand that your experience differs, though, so here's a handful of
situations that would be excellent candidates for the new feature:
1. Likely the most common case, for me, is when I have some data and want to
iterate over both it and a calculated pairing:
>>> x = ["a", "b", "c", "d"]
>>> y = iter_apply_some_transformation(x)
>>> for a, b in zip(x, y):
... ... # Do something.
...
This can be extrapolated to many more cases, where x and/or y are constants,
iterators, calculated from each other, calculated individually, passed as
arguments, etc. I've written most of them in production code, and in every
case, mismatched lengths are logic errors that should "never" happen. A
`ValueError` which (a) kills the job, (b) logs the bad data and proceeds to the
next job, or (c) alerts me to my error in an interactive session or
unit/property test is always better than a silently incomplete result.
2. This is less-well-known, but you can lazily unzip/"transpose" nested
iterables by unpacking into `zip`. I've seen it suggested many times on
StackOverflow:
>>> x = iter((iter((0, 1, 2)), iter((3, 4, 5)), iter((6, 7, 8))))
>>> y = zip(*x)
>>> tuple(y)
((0, 3, 6), (1, 4, 7), (2, 5, 8))
It's clearly a logic error if one of the tuples in `x` is longer/shorter than
the others, but this move would silently toss the data instead.
3. Just to show that this has visible effects in the stdlib: below is the AST
equivalent of `eval("{'KEY WITH NO VALUE': }")`. The use of `zip` to implement
`ast.literal_eval` silently throws away the bad key, instead of complaining
with a `ValueError` (as it typically does for malformed or invalid input).
>>> from ast import Constant, Dict, literal_eval
>>> malformed = Dict(keys=[Constant("KEY WITH NO VALUE")], values=[])
>>> literal_eval(malformed)
{}
So it's not a difficult mistake to make.
> ...it seems to me that you are incorrect, zip does not already handle the
> case of unequal iterators internally.
Yeah, I misspoke here. In my defense, though, I've made this point several
times, and in those cases I was careful to note that it handles *most of* the
logic (you're right that one additional iterator pull is required if the first
iterable is the "short" one).
My point was not that this change is a one-liner or something, but rather that
it doesn't require significant changes to the `zip.__next__` logic and should
be effectively no-overhead for strict and non-strict users alike in all but the
most pathological cases. Even more important: it's dead-simple to read, write,
understand, and maintain. I don't feel the same can be said of sentinels and
zip_longest.
>> I know that I, and everyone on my team, would use it frequently!
> Use it frequently for what? "We would use it!" is not a use-case. How would
> you use it?
Well, the comment I was replying to wasn't asking for a use-case, or even
arguing against the proposal. They were just asserting that few would use it if
it wasn't the default behavior. I felt the need to speak up that, yes, *most*
of the engineers I interact with regularly certainly would. But now it's been
quoted more times than any of my actual comments on the proposal, so shame on
me for the poor wording which doesn't quote well.
For use-cases, see above.
_______________________________________________
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/HPCMXOFU7HERIGYYD6XUJQQKYRES5NT3/
Code of Conduct: http://python.org/psf/codeofconduct/