[Python-Dev] (no subject)

Neil Girdhar mistersheik at gmail.com
Tue Feb 10 01:29:44 CET 2015


For some reason I can't seem to reply using Google groups, which is is
telling "this is a read-only mirror" (anyone know why?)  Anyway, I'm going
to answer as best I can the concerns.

Antoine said:

To be clear, the PEP will probably be useful for one single line of
> Python code every 10000. This is a very weak case for such an intrusive
> syntax addition. I would support the PEP if it only added the simple
> cases of tuple unpacking, left alone function call conventions, and
> didn't introduce **-unpacking.


To me this is more of a syntax simplification than a syntax addition.  For
me the **-unpacking is the most useful part. Regarding utility, it seems
that a many of the people on r/python were pretty excited about this PEP:
http://www.reddit.com/r/Python/comments/2synry/so_8_peps_are_currently_being_proposed_for_python/

—

Victor noticed that there's a mistake with the code:

>>> ranges = [range(i) for i in range(5)]
> >>> [*item for item in ranges]
> [0, 0, 1, 0, 1, 2, 0, 1, 2, 3]


It should be a range(4) in the code.  The "*" applies to only item.  It is
the same as writing:

[*range(0), *range(1), *range(2), *range(3), *range(4)]

which is the same as unpacking all of those ranges into a list.

> function(**kw_arguments, **more_arguments)
> If the key "key1" is in both dictionaries, more_arguments wins, right?


There was some debate and it was decided that duplicate keyword arguments
would remain an error (for now at least).  If you want to merge the
dictionaries with overriding, then you can still do:

function(**{**kw_arguments, **more_arguments})

because **-unpacking in dicts overrides as you guessed.

—



On Mon, Feb 9, 2015 at 7:12 PM, Donald Stufft <donald at stufft.io> wrote:

>
> On Feb 9, 2015, at 4:06 PM, Neil Girdhar <mistersheik at gmail.com> wrote:
>
> Hello all,
>
> The updated PEP 448 (https://www.python.org/dev/peps/pep-0448/) is
> implemented now based on some early work by Thomas Wouters (in 2008) and
> Florian Hahn (2013) and recently completed by Joshua Landau and me.
>
> The issue tracker http://bugs.python.org/issue2292  has  a working
> patch.  Would someone be able to review it?
>
>
> I just skimmed over the PEP and it seems like it’s trying to solve a few
> different things:
>
> * Making it easy to combine multiple lists and additional positional args
> into a function call
> * Making it easy to combine multiple dicts and additional keyword args
> into a functional call
> * Making it easy to do a single level of nested iterable "flatten".
>

I would say it's:
* making it easy to unpack iterables and mappings in function calls
* making it easy to unpack iterables  into list and set displays and
comprehensions, and
* making it easy to unpack mappings into dict displays and comprehensions.



>
> Looking at the syntax in the PEP I had a hard time detangling what exactly
> it was doing even with reading the PEP itself. I wonder if there isn’t a
> way to combine simpler more generic things to get the same outcome.
>
> Looking at the "Making it easy to combine multiple lists and additional
> positional args into a  function call" aspect of this, why is:
>
> print(*[1], *[2], 3) better than print(*[1] + [2] + [3])?
>
> That's already doable in Python right now and doesn't require anything new
> to handle it.
>

Admittedly, this wasn't a great example.  But, if [1] and [2] had been
iterables, you would have to cast each to list, e.g.,

accumulator = []
accumulator.extend(a)
accumulator.append(b)
accumulator.extend(c)
print(*accumulator)

replaces

print(*a, b, *c)

where a and c are iterable.  The latter version is also more efficient
because it unpacks only a onto the stack allocating no auxilliary list.


> Looking at the "making it easy to do a single level of nsted iterable
> 'flatten'"" aspect of this, the example of:
>
> >>> ranges = [range(i) for i in range(5)]
> >>> [*item for item in ranges]
> [0, 0, 1, 0, 1, 2, 0, 1, 2, 3]
>
> Conceptually a list comprehension like [thing for item in iterable] can be
> mapped to a for loop like this:
>
> result = []
> for item in iterable:
>     result.append(thing)
>
> However [*item for item in ranges] is mapped more to something like this:
>
> result = []
> for item in iterable:
>     result.extend(*item)
>
> I feel like switching list comprehensions from append to extend just
> because of a * is really confusing and it acts differently than if you just
> did *item outside of a list comprehension. I feel like the
> itertools.chain() way of doing this is *much* clearer.
>
> Finally there's the "make it easy to combine multiple dicts into a
> function call" aspect of this. This I think is the biggest thing that this
> PEP actually adds, however I think it goes around it the wrong way. Sadly
> there is nothing like [1] + [2] for dictionaries. The closest thing is:
>
> kwargs = dict1.copy()
> kwargs.update(dict2)
> func(**kwargs)
>
> So what I wonder is if this PEP wouldn't be better off just using the
> existing methods for doing the kinds of things that I pointed out above,
> and instead defining + or | or some other symbol for something similar to
> [1] + [2] but for dictionaries. This would mean that you could simply do:
>
> func(**dict1 | dict(y=1) | dict2)
>
> instead of
>
> dict(**{'x': 1}, y=2, **{'z': 3})
>
> I feel like not only does this genericize way better but it limits the
> impact and new syntax being added to Python and is a ton more readable.
>
>
> ---
> Donald Stufft
> PGP: 7C6B 7C5D 5E2B 6356 A926 F04F 6E3C BCE9 3372 DCFA
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20150209/2ae932a2/attachment.html>


More information about the Python-Dev mailing list