This PEP proposes a change to iterable unpacking syntax, allowing tospecify a “catch-all” name which will be assigned a list of all itemsnot assigned to a “regular” name.
An example says more than a thousand words:
>>>a,*b,c=range(5)>>>a0>>>c4>>>b[1, 2, 3]
Many algorithms require splitting a sequence in a “first, rest” pair.With the new syntax,
first,rest=seq[0],seq[1:]
is replaced by the cleaner and probably more efficient:
first,*rest=seq
For more complex unpacking patterns, the new syntax looks evencleaner, and the clumsy index handling is not necessary anymore.
Also, if the right-hand value is not a list, but an iterable, ithas to be converted to a list before being able to do slicing; toavoid creating this temporary list, one has to resort to
it=iter(seq)first=it.next()rest=list(it)
A tuple (or list) on the left side of a simple assignment (unpackingis not defined for augmented assignment) may contain at most oneexpression prepended with a single asterisk (which is henceforthcalled a “starred” expression, while the other expressions in thelist are called “mandatory”). This designates a subexpression thatwill be assigned a list of all items from the iterable being unpackedthat are not assigned to any of the mandatory expressions, or anempty list if there are no such items.
For example, ifseq is a sliceable sequence, all the followingassignments are equivalent ifseq has at least two elements:
a,b,c=seq[0],list(seq[1:-1]),seq[-1]a,*b,c=seq[a,*b,c]=seq
It is an error (as it is currently) if the iterable doesn’t containenough items to assign to all the mandatory expressions.
It is also an error to use the starred expression as a loneassignment target, as in
*a=range(5)
This, however, is valid syntax:
*a,=range(5)
Note that this proposal also applies to tuples in implicit assignmentcontext, such as in afor statement:
fora,*bin[(1,2,3),(4,5,6,7)]:print(b)
would print out
[2,3][5,6,7]
Starred expressions are only allowed as assignment targets, using themanywhere else (except for star-args in function calls, of course) is anerror.
This feature requires a new grammar rule:
star_expr:['*']expr
In these two rules,expr is changed tostar_expr:
comparison:star_expr(comp_opstar_expr)*exprlist:star_expr(','star_expr)*[',']
A new ASDL expression typeStarred is added which represents astarred expression. Note that the starred expression elementintroduced here is universal and could later be used for otherpurposes in non-assignment context, such as theyield*iterableproposal.
The compiler is changed to recognize all cases where a starredexpression is invalid and flag them with syntax errors.
A new bytecode instruction,UNPACK_EX, is added, whose argumenthas the number of mandatory targets before the starred target in thelower 8 bits and the number of mandatory targets after the starredtarget in the upper 8 bits. For unpacking sequences without starredexpressions, the oldUNPACK_ITERABLE opcode is kept.
The functionunpack_iterable() in ceval.c is changed to handlethe extended unpacking, via anargcntafter parameter. In theUNPACK_EX case, the function will do the following:
Shortcuts for unpacking iterables of known types, such as lists ortuples, can be added.
The current implementation can be found at the SourceForge Patchtracker[SFPATCH]. It now includes a minimal test case.
After a short discussion on the python-3000 list[1], the PEP wasaccepted by Guido in its current form. Possible changes discussedwere:
b ina,*b='hello' would beassigned the string'ello'. This may seem nice, but isimpossible to get right consistently with all iterables.*args, but make further processingof the result harder.This document has been placed in the public domain.
Source:https://github.com/python/peps/blob/main/peps/pep-3132.rst
Last modified:2025-02-01 08:59:27 GMT