On Mon, Apr 20, 2020 at 07:47:51PM -0700, Andrew Barnert wrote: > >> counter = itertools.count() > >> yield from zip(counter, itertools.chain(headers, [''], body, ['']) > >> lines = next(counter) > > > > That gives you one more than the number of lines yielded. > > Yeah, I screwed that up in simplifying the real code without testing > the result. And your version gives one _less_ than the number yielded.
No, my version repeats the last number yielded, which is precisely what you wanted (as I understand it). See below. py> def test(): ... headers = body = '' ... for t in enumerate(itertools.chain(headers, [''], body, [''])): ... yield t ... print(t[0]) ... py> list(test()) 1 [(0, ''), (1, '')] > (With either enumerate(xs) or zip(counter, xs) the last element will > be (len(xs)-1, xs[-1]). Um, yes? That's because both enumerate and counter start from zero by default. I would have asked you why you were counting your lines starting from zero instead of using `enumerate(xs, 1)` but I thought that was intentional. > Your version has the additional problem that > if the iterable is empty, t is not off by one but unbound (or bound to > some stale old value)—but that’s not possible in my example, and > probably not in most similar examples. But the iterable is never empty, because you always yield at least two blanks. > Anyway, that’s exactly why I want to make sure the fencepost behavior > is actually defined for this new proposal. Any reasonable answer is > probably fine; people probably won’t run into wanting the leftovers, > but if they ever do, as long as the docs say what should be there, > they’ll work it out. Like you worked out the behaviour of counter and zip? *wink* I think you were overthinking it. The simplest, foolproof way to get the number of items yielded is to count them with enumerate starting with 1: count = 0 for count, item in enumerate(something, 1): yield item print(count) I don't believe this zip_strict proposal would help you in this situation. I think it will make it worse, because it will encourage people to use this anti-pattern: seq = list(something) for count, item in zip_strict(range(1, len(seq)+1), seq): yield item print(count) "just to be sure". -- Steven _______________________________________________ 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/WAPV6KEAW6PREDBMS47OVSTYNQWEON3K/ Code of Conduct: http://python.org/psf/codeofconduct/