[Python-ideas] Enhancing dict.values
Steven D'Aprano
steve at pearwood.info
Fri May 27 12:17:40 EDT 2016
On Fri, May 27, 2016 at 06:43:35AM -0700, Steve Dower wrote:
> Neat!
>
> My bikeshed is coloured `dict.getmany(*keys, default=None)`,
"getmany" doesn't tell you, many of what?
> and while
> returning a namedtuple might be cool, an iterator is probably the way
> to go.
The disadvantage of a namedtuple is that every invocation would create a
new class, which is then used once and once only for a singleton
instance. Could get very expensive.
I don't think an iterator would be needed. The motivating use-case is
for sequence unpacking:
# apologies for breaking my own rule about realistic names
fee, fi, fo, fum = mydict.getmany('fee', 'fi', 'fo', 'fum')
so I don't think the lazy aspect of an iterator is useful. It's going to
be consumed eagerly, and immediately. I think a regular tuple is better.
That also matches the behaviour of itemgetter:
py> d = {'fe': 1, 'fi': 2, 'fo': 3, 'fum': 4}
py> from operator import itemgetter
py> f = itemgetter('fe', 'fi', 'fo', 'fum')
py> f(d)
(1, 2, 3, 4)
So the core functionality already exists, it's just hidden away in the
operator module. (Guido's time machine strikes again.)
Open questions:
- Is it worth making this a dict method? +1 from me.
- Name? "getvalues"?
- Any other functionality?
Possibly a keyword-only "default" argument:
mydict.getvalues(*keys, default=None)
On more shaky ground, how about a "pop" argument?
mydict.getvalues(*keys, pop=True)
will delete the keys as well as return the values. Use-case: methods
(particularly __init__ or __new__) which take extra keyword args which
need to be popped before calling super.
def __init__(self, **kwargs):
colour, height = kwargs.getvalues('colour', 'height', pop=True)
super().__init__(**kwargs)
self.process(colour, height)
--
Steve
More information about the Python-ideas
mailing list