[Python-ideas] Default values in multi-target assignment
Clint Hepner
clint.hepner at gmail.com
Thu Apr 12 08:28:11 EDT 2018
> On 2018 Apr 12 , at 5:54 a, Serhiy Storchaka <storchaka at gmail.com> wrote:
>
> Yet one crazy idea. What if allow default values for targets in multi-target assignment?
>
> >>> (a, b=0) = (1, 2)
> >>> a, b
> (1, 2)
> >>> (a, b=0) = (1,)
> >>> a, b
> (1, 0)
> >>> (a, b=0) = ()
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> ValueError: not enough values to unpack (expected at least 1, got 0)
> >>> (a, b=0) = (1, 2, 3)
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> ValueError: too many values to unpack (expected at most 2)
>
> Currently you need either explicitly check the length of the right-hand part (if it is a sequence and not an arbitrary iterator),
>
> if len(c) == 1:
> a, = c
> b = 0
> elif len(c) == 2:
> a, b = c
> else:
> raise TypeError
>
> or use an intermediate function:
>
> def f(a, b=0):
> return a, b
> a, b = f(*c)
>
> The latter can be written as an ugly one-liner:
>
> a, b = (lambda a, b=0: (a, b))(*c)
I think the best comparison would be
(a, b=0, *_) = t
vs
a, b, *_ = (*t, 0)
(a, b, *_) = (*t, 0)
In both, I've added *_ to capture any trailing elements. It's
more necessary with the current syntax, since adding defaults
will make the tuple too long when they aren't needed.
Given that, I'm +1 on the proposal, since
1. Defaults are more closely associated with their intended name
2. A new tuple doesn't need to be constructed on the RH
The one minor downside, IMO, is that if you choose to omit the *_ guard,
you *must* use parentheses on the LHS, as
a, b = 0 = t # parsed as a, b = (0 = t)
raises a SyntaxError on the assignment to 0.
--
Clint
More information about the Python-ideas
mailing list