Chris Angelico wrote: > On Mon, Dec 8, 2014 at 5:27 AM, Ian Kelly <ian.g.ke...@gmail.com> wrote: >> On Dec 7, 2014 8:31 AM, "Ned Batchelder" <n...@nedbatchelder.com> wrote: >>> NOTE: THIS EXAMPLE IS HORRIBLE. This code is crazy-confusing, and >>> should never have been used as an example of iteration. It layers at >>> least three iterations on top of each other, making it very difficult to >>> see what is >>> going on. It uses "while iters" where "while True" would do exactly the >>> same thing (iters will never be false). >> >> That's not quite correct; the "while iters" actually guards against the >> case where the passed args are empty. With no sub-iterators, no >> StopIteration would ever be raised, and the result would be an infinite >> generator of empty tuples. The "while iters" makes it return immediately >> instead. >> >> So it seems this example is even more confusing than you thought. > > I'm actually glad PEP 479 will break this kind of code. Gives a good > excuse for rewriting it to be more readable.
What kind of code is that? Short, simple, Pythonic and elegant? :-) Here's the code again, with indentation fixed: def myzip(*args): iters = map(iter, args) while iters: res = [next(i) for i in iters] yield tuple(res) That is *beautiful code*. It's written for Python 2, where map returns a list, so the "while iters" line is morally equivalent to: while iters != [] and True It would be even more beautiful if we get rid of the unnecessary temporary variable: def myzip(*args): iters = map(iter, args) while iters: yield tuple([next(i) for i in iters]) I think this function makes a good test to separate the masters from the apprentices. No offence intended to Ned, who is a master, anyone can have a bad day or a blind spot. If you can read this function and instantly tell how it works, that it is bug-free and duplicates the behaviour of the built-in zip(), you're probably Raymond Hettinger. If you can tell what it does but you have to think about it for a minute or two before you understand why it works, you can call yourself a Python master. If you have to sit down with the interactive interpreter and experiment for a bit to understand it, you're doing pretty well. I do not believe that good code must be obviously right. It's okay for code to be subtly right. Either is better than complicated code which contains no obvious bugs. How would we re-write this to work in the future Python 3.7? Unless I have missed something, I think we could write it like this: def myzip37(*args): iters = list(map(iter, args)) while iters: try: yield tuple([next(i) for i in iters]) except StopIteration: return which I guess is not too horrible. If Python had never supported the current behaviour, I'd probably be happy with this. But having seen how elegant generators *can* be, the post-PEP 479 version will always look bloated and clumsy to me, like Garfield next to a cheetah. -- Steven -- https://mail.python.org/mailman/listinfo/python-list