> 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 -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/HPCMXOFU7HERIGYYD6XUJQQKYRES5NT3/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to