Reputation: 32997
I was writing some code and made a typo, but it didn't error. Tracing it back, I found out that these work:
>>> [] = []
>>> () = ()
>>>
This is iterable unpacking, but with no real target for assignment. Why does Python allow this? Are there situations where this is useful?
Here's where it's defined in the grammar. I would have thought you'd need at least one identifier, attributeref, subscription, or slicing, but apparently not; target_list is optional inside parentheses or brackets.
target ::= identifier
| "(" [target_list] ")"
| "[" [target_list] "]"
| attributeref
| subscription
| slicing
| "*" target
Looking at the documentation history, this wasn't possible as recently as Python 3.4 and 2.6, but assigning to []
was added in Python 3.5 and 2.7, and ()
in Python 3.6.
Related:
Note: Since I'm asking about a design choice, answers should include references to authoritative sources like official documentation or a core dev.
Upvotes: 3
Views: 291
Reputation: 32997
Based on the relevant Python issue discussion, assigning to an empty list []
was actually possible for a long time, but not documented. This was considered "a fairly harmless quirk" until it was documented in 3.5. Then assigning to an empty tuple ()
was added for consistency.
In the same thread, Martin Panter provides a possible use case:
[...] I have used this syntax on purpose as a concise way to ensure that a generator is exhaused with no more yields:
>>> def gen(): ... yield "partial computation" ... print("computation allowed to complete") ... >>> g = gen() >>> next(g) 'partial computation' >>> [] = g computation allowed to complete
Upvotes: 5