[Python-ideas] Dictionary destructing and unpacking.
Oleg Broytman
phd at phdru.name
Thu Jun 8 01:51:39 EDT 2017
Thank you! This overview really helps!
On Thu, Jun 08, 2017 at 11:18:06AM +1000, Steven D'Aprano <steve at pearwood.info> wrote:
> On Wed, Jun 07, 2017 at 06:14:08PM +0000, Nick Humrich wrote:
>
> > It would be cool to have a syntax that would unpack the dictionary to
> > values based on the names of the variables. Something perhaps like:
> >
> > a, b, c = **mydict
>
> This was discussed (briefly, to very little interest) in March/April
> 2008:
>
> https://mail.python.org/pipermail/python-ideas/2008-March/001511.html
> https://mail.python.org/pipermail/python-ideas/2008-April/001513.html
>
> and then again in 2016, when it spawned a very large thread starting
> here:
>
> https://mail.python.org/pipermail/python-ideas/2016-May/040430.html
>
> I know there's a lot of messages, but I STRONGLY encourage anyone,
> whether you are for or against this idea, to read the previous
> discussion before continuing it here.
>
> Guido was luke-warm about the **mapping syntax:
>
> https://mail.python.org/pipermail/python-ideas/2016-May/040466.html
>
> Nathan Schneider proposed making dict.values() take optional key names:
>
> https://mail.python.org/pipermail/python-ideas/2016-May/040517.html
>
> Guido suggested that this should be a different method:
>
> https://mail.python.org/pipermail/python-ideas/2016-May/040518.html
>
> My recollection is that the discussion evertually petered out with a
> more-or-less consensus that having a dict method (perhaps "getvalues"?)
> plus regular item unpacking is sufficient for the common use-case of
> unpacking a subset of keys:
>
> prefs = {'width': 80, 'height': 200, 'verbose': False, 'mode': PLAIN,
> 'name': 'Fnord', 'flags': spam|eggs|cheese, ... }
> # dict includes many more items
>
> width, height, size = prefs.getvalues(
> 'width', 'height', 'papersize',
> )
>
>
> This trivially supports the cases where keys are not strings or valid
> identifiers:
>
> class_, spam, eggs = mapping.getvalues('class', 42, '~')
>
> It easily supports assignment targets which aren't simple variable
> names:
>
> obj.attribute[index], spam().attr = mapping.getvalues('foo', 'bar')
>
> An optional (defaults to False) "pop" keyword argument supports
> extracting and removing values from the dict in one call, which is
> commonly needed inside __init__ methods with **kwargs:
>
> class K(parent):
> def __init__(self, a, b, c, **kwargs):
> self.spam = kwargs.pop('spam')
> self.eggs = kwargs.pop('eggs')
> self.cheese = kwargs.pop('cheese')
> super().__init__(a, b, c, **kwargs)
>
>
> becomes:
>
> self.spam, self.eggs, self.cheese = kwargs.getvalues(
> 'spam eggs cheese'.split(), pop=True
> )
>
>
> I don't recall this being proposed at the time, but we could support
> keyword arguments for missing or default values:
>
> DEFAULTS = {'height': 100, 'width': 50}
> prefs = get_prefs() # returns a dict
>
> height, width, size = prefs.getvalues(
> 'height', 'width', 'papersize',
> defaults=DEFAULTS,
> missing=None
> )
>
>
> A basic implementation might be:
>
> # Untested.
> def getvalues(self, *keys, pop=False, defaults=None, missing=SENTINEL):
> values = []
> for key in keys:
> try:
> x = self[key]
> except KeyError:
> if defaults is not None:
> x = defaults.get(key, SENTINEL)
> if x is SENTINEL:
> x = missing
> if x is SENTINEL:
> raise KeyError('missing key %r' % key)
> if pop:
> del self[key]
> values.append(x)
> return tuple(values)
>
>
>
> It's a bit repetitive for the common case where keys are the same as the
> assignment targets, but that's a hard problem to solve, and besides,
> "explicit is better than implicit".
>
> It also doesn't really work well for the case where you want to blindly create new assignment targets for
> *every* key, but:
>
> - my recollection is that nobody really came up with a convincing
> use-case for this (apologies if I missed any);
>
> - and if you really need this, you can do:
>
> locals().update(mapping)
>
> inside a class body or at the top-level of the module (but not inside a
> function).
>
> Please, let's save a lot of discussion here and now, and just read the
> 2016 thread: it is extremely comprehensive.
>
>
> --
> Steve
Oleg.
--
Oleg Broytman http://phdru.name/ phd at phdru.name
Programmers don't die, they just GOSUB without RETURN.
More information about the Python-ideas
mailing list