This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Extended slice assignment + iterable unpacking
Type: enhancement Stage: resolved
Components: Interpreter Core Versions: Python 3.8
process
Status: closed Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: Windson Yang, georg.brandl, gvanrossum, serhiy.storchaka, wim.glenn
Priority: normal Keywords:

Created on 2019-04-30 18:48 by wim.glenn, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (4)
msg341160 - (view) Author: wim glenn (wim.glenn) * Date: 2019-04-30 18:48
Could cases like these be made to work? *Should* cases like these be made to work?

L = [0, 1, 2]
L[::2], *rest = "abcdef"
# ValueError: attempt to assign sequence of size 1 to extended slice of size 2

a, L[::2] = "abc"
# ValueError: too many values to unpack (expected 2)

The list slice knows exactly how many slots need to be filled, so I can't immediately think of any obvious ambiguity. Maybe there are some implementation complications with supporting e.g. generators on the RHS (because RHS must be evaluated before LHS - https://docs.python.org/3/reference/expressions.html#evaluation-order).
msg341183 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2019-05-01 09:23
For the second case, you can use

a, *L[::2] = "abc"

For the first case this does not work, because an assignment can have only one starred expression.

Making the first case to work as you expected is breaking change. Currently

L[:], *rest = 'abcdef'

sets L to ['a'] and rest to ['b', 'c', 'd', 'e', 'f']. Consistent implementing of your idea would set L to ['a', 'b', 'c'] and rest to ['d', 'e', 'f'] (because len(L[:]) == 3 before assignment).

What is your use case? Why do you need such syntax?
msg341242 - (view) Author: Windson Yang (Windson Yang) * Date: 2019-05-02 01:22
In your first case, *any positive index except 2 will work*, For example:

L = [0, 1, 2]
L[::1], *rest = "abcdef" # L became ['a']
or 
L[::3], *rest = "abcdef" # L became ['a', 1, 2]

I found iff when you change the length of L to 1(L[::3]) or didn't change L at all (L[::1], L[::]), this expression will work. But I'm not sure that is what you expected.
msg342389 - (view) Author: wim glenn (wim.glenn) * Date: 2019-05-13 21:33
Serhiy,

`a, *L[::2] = "abc"` as an alternative is interesting, thanks.  The other example `L[:], *rest = 'abcdef'` is less interesting because L[:] can be arbitrary size.

When noticing this, I had tried to consume a generator into every other position in a list by using:

    L[::2], *extra = g

Though there are obvious workarounds (e.g. using `itertools.islice`), it surprised me that CPython did not "do what I mean" out of the box. 

However, since creating the issue, it was brought to my attention that trying to handle this assignment may result in potential ambiguity, for example:

    L = [0, 1, 2]
    L[::2], *rest = "ab", "c", "d"

There is no obvious choice for result here. So, perhaps this issue should just be closed.
History
Date User Action Args
2022-04-11 14:59:14adminsetgithub: 80942
2020-01-09 00:54:32wim.glennsetstatus: open -> closed
stage: resolved
2019-05-13 21:33:08wim.glennsetmessages: + msg342389
2019-05-02 01:22:34Windson Yangsetnosy: + Windson Yang
messages: + msg341242
2019-05-01 09:23:10serhiy.storchakasetnosy: + serhiy.storchaka
messages: + msg341183
2019-05-01 07:07:31SilentGhostsetnosy: + gvanrossum, georg.brandl

versions: + Python 3.8
2019-04-30 18:48:02wim.glenncreate