I wanna propose making generators even weirder!
so, extended continue is an oldie:
https://www.python.org/dev/peps/pep-0342/#the-extended-continue-statement
it'd allow one to turn:
yield from foo
into:
for bar in foo:
continue (yield bar)
but what's this extended for-else? well, currently you have for-else:
for x, y, z in zip(a, b, c):
...
else:
pass
and this works. you get the stuff from the iterators, and if you break
the loop, the else doesn't run. the else basically behaves like "except
StopIteration:"...
so I propose an extended for-else, that behaves like "except
StopIteration as foo:". that is, assuming we could get a zip() that
returns partial results in the StopIteration (see other threads), we
could do:
for x, y, z in zip(a, b, c):
do_stuff_with(x, y, z)
else as partial_xy:
if len(partial_xy) == 0:
x = dummy
try:
y = next(b)
except StopIteration: y = dummy
try:
z = next(c)
except StopIteration: z = dummy
if (x, y, z) != (dummy, dummy dummy):
do_stuff_with(x, y, z)
if len(partial_xy) == 1:
x, = partial_xy
y = dummy
try:
z = next(c)
except StopIteration: z = dummy
do_stuff_with(x, y, z)
if len(partial_xy) == 2:
x, y = partial_xy
z = dummy
do_stuff_with(x, y, z)
(this example is better served by zip_longest. however, it's
nevertheless a good way to demonstrate functionality, thanks to
zip_longest's (and zip's) trivial/easy to understand behaviour.)
this would enable one to turn:
return yield from foo
into:
for bar in foo:
continue (yield bar)
else as baz:
return baz
allowing one to pick apart and modify the yielded and sent parts, while
still getting access to the return values.
currently if you have an arbitrary generator, you can't modify the
yielded values without breaking send or return. in fact you can either
pass-through yield and send and collect the return, or modify yield and
forget about send and the return, or use very ugly syntax that makes
everything look lower-level than it should, to be able to pick apart
everything:
try:
bar = next(foo)
except StopIteration as exc:
baz = exc.value
else:
while True:
try:
bar = foo.send((yield bar))
except StopIteration as exc:
baz = exc.value
break
return baz
(this is exactly equivalent (if I didn't overlook anything) to the
previous endearingly simple loop with extended for-else and extended
continue)
_______________________________________________
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/4NZXWPOCV6CSM3CBIN4UDQGRWCVENCTY/
Code of Conduct: http://python.org/psf/codeofconduct/