[Python-ideas] How assignment should work with generators?

Kirill Balunov kirillbalunov at gmail.com
Mon Nov 27 04:17:31 EST 2017


Currently during assignment, when target list is a comma-separated list of
targets (*without "starred" target*) the rule is that the object (rhs) must
be an iterable with the same number of items as there are targets in the
target list. That is, no check is performed on the number of targets
present, and if something goes wrong the  ValueError is raised. To show
this on simple example:

>>> from itertools import count, islice
>>> it = count()
>>> x, y = it
>>> it
count(3)

Here the count was advanced two times but assignment did not happen. I
found that in some cases it is too much restricting that rhs must have the
same number of items as targets. It is proposed that if the rhs is a
generator or an iterator (better some object that yields values on demand),
the assignmenet should be lazy and dependent on the number of targets. I
find this feature to be very convenient for interactive use, while it
remains readable, expected, and expressed in a more compact code.

There are some Pros:
    1. No overhead
    2. Readable and not so verbose code
    3. Optimized case for x,y,*z = iterator
    4. Clear way to assign values partially from infinite generators.

Cons:
    1. A special case of how assignment works
    2. As with any implicit behavior, hard-to-find bugs

There several cases with "undefined" behavior:
1. Because the items are assigned, from left to right to the corresponding
targets, should rhs see side effects during assignment or not?
2. Should this work only for generators or for any iterators?
3. Is it Pythonic to distinguish what is on the rhs during assignment, or
it contradicts with duck typing (goose typing)?

In many cases it is possible to do this right now, but in too verbose way:

>>> x, y = islice(gen(), 2)

But it seems for me that:

>>> x, y = gen()

Looks the same, easy to follow and not so verbose. Another case, which is a
pitfall, but will be possible:

>>> x, y = iter([0,1,2,3,4]) # Now it is Ok
>>> x
1
>>> y
2

But:

>>> x, y = [0,1,2,3,4]       # raises ValueError

Any thoughts?

With kind regards, -gdg
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20171127/daa7069c/attachment.html>


More information about the Python-ideas mailing list