[Python-ideas] Fwd: Fwd: unpacking generalisations for list comprehension

Random832 random832 at fastmail.com
Thu Oct 13 17:30:49 EDT 2016


On Thu, Oct 13, 2016, at 16:59, Paul Moore wrote:
> I don't (for the reasons raised before). But thank you for your
> explanation, it clarifies what you were proposing. And it does so
> within the *current* uses of the * symbol, which is good. But:
> 
> 1. I'm not keen on extending append's meaning to overlap with extend's
> like this.

I think the "append(*x)" bit was just a flourish to try to explain it in
terms of the current use of * since you don't seem to understand it any
other way, rather than an actual proposal to actually change the append
method.

> 2. Your proposal does not generalise to generator expressions, set
> displays (without similarly modifying the set.add() method) or
> dictionary displays.

Basically it would make the following substitutions in the conventional
"equivalent loops"
generator yield => yield from
list append => extend
set add => update
dict __setitem__ => update

dict comprehensions would need to use **x - {*x for x in y} would be a
set comprehension.

> 3. *fn(x) isn't an expression, and yet it *looks* like it should be,
> and in the current syntax, an expression is required in that position.
> To me, that suggests it would be hard to teach. [1]

I can think of another position an expression used to be required in:

Python 3.5.2
>>> [1, *(2, 3), 4]
[1, 2, 3, 4]

Python 2.7.11
>>> [1, *(2, 3), 4]
  File "<stdin>", line 1
    [1, *(2, 3), 4]
        ^
SyntaxError: invalid syntax

Was that hard to teach? Maybe. But it's a bit late to object now, and
every single expression on the right hand side in my examples below
already has a meaning.


Frankly, I don't see why the pattern isn't obvious [and why people keep
assuming there will be a new meaning of f(*x) as if it doesn't already
have a meaning]

Lists, present:
   [x for x in [a, b, c]] == [a, b, c]
   [f(x) for x in [a, b, c]] == [f(a), f(b), f(c)]
   [f(*x) for x in [a, b, c]] == [f(*a), f(*b), f(*c)]
   [f(**x) for x in [a, b, c]] == [f(**a), f(**b), f(**c)]
Lists, future:
   [*x for x in [a, b, c]] == [*a, *b, *c]
   [*f(x) for x in [a, b, c]] == [*f(a), *f(b), *f(c)]
   [*f(*x) for x in [a, b, c]] == [*f(*a), *f(*b), *f(*c)]
   [*f(**x) for x in [a, b, c]] == [*f(**a), *f(**b), *f(**c)]

Sets, present:
   {x for x in [a, b, c]} == {a, b, c}
   {f(x) for x in [a, b, c]} == {f(a), f(b), f(c)}
   {f(*x) for x in [a, b, c]} == {f(*a), f(*b), f(*c)}
   {f(**x) for x in [a, b, c]} == {f(**a), f(**b), f(**c)}
Sets, future:
   {*x for x in [a, b, c]} == {*a, *b, *c}
   {*f(x) for x in [a, b, c]} == {*f(a), *f(b), *f(c)}
   {*f(*x) for x in [a, b, c]} == {*f(*a), *f(*b), *f(*c)}
   {*f(**x) for x in [a, b, c]} == {*f(**a), *f(**b), *f(**c)}

Dicts, future:
   {**x for x in [a, b, c]} == {**a, **b, **c}
   {**f(x) for x in [a, b, c]} == {**f(a), **f(b), **f(c)}
   {**f(*x) for x in [a, b, c]} == {**f(*a), **f(*b), **f(*c)}
   {**f(**x) for x in [a, b, c]} == {**f(**a), **f(**b), **f(**c)}


More information about the Python-ideas mailing list