[Python-ideas] Add a method to get the subset of a dictionnary.
Steven D'Aprano
steve at pearwood.info
Sat Nov 12 03:32:33 EST 2016
On Wed, Oct 12, 2016 at 06:06:51PM +0200, Enguerrand Pelletier wrote:
> Hi all,
>
> It always bothered me to write something like this when i want to strip
> keys from a dictionnary in Python:
>
> a = {"foo": 1, "bar": 2, "baz": 3, "foobar": 42}
> interesting_keys = ["foo", "bar", "baz"]
> b = {k, v for k,v in a.items() if k in interesting_keys}
(You have a small typo: should be "k: v" not "k, v".)
Why does it bother you? It is simple, easy to understand, and explict.
> Wouldn't it be nice to have a syntactic sugar such as:
Syntactic sugar is not really the right term, "syntactic sugar" means a
special form of syntax as a short-cut for something longer. This is not
special syntax, it is just a method.
> b = a.subset(interesting_keys)
Personally, I have never missed this method, but if I did, it would be
easy to make a helper function:
def subset(adict, keys):
"""Return a new dict from existing keys."""
return {k: v for k,v in a.items() if k in keys}
Not every simple helper function needs to be built-in to the class. That
is the beauty of Python, you can make your own helper functions, once
you give up the idea that everything needs to be a method.
There are some problems with making this a method. To start with, it
means that every dict and mapping would have to support it. Perhaps that
is acceptible, but it does mean that the question is bigger than just
dict. It also involves:
ChainMap
Counter
Mapping
MutableMapping
OrderedDict
UserDict
defaultdict
at the very least. (Perhaps this is easy to implement, by just adding
this to the Mapping ABC and letting everything else inherit from that.
But even so, it increases the complexity of the entire Mapping ABC and
all its classes.)
But a bigger problem with making this a built-in dict method is deciding
exactly what it should do. Here are some options:
- should the method return a new dict, or modify the existing dict?
- should it keep the "interesting keys" or remove them?
- is it an error if one of the interesting keys is missing?
- or should it be silently skipped?
- or automatically added? using what value?
Whatever options we pick here, you can be sure that some people will
want a different set of options.
Unless we are sure that one combination is much more common than the
other combinations, we're better off letting people write their own
helper functions that behave exactly as they want:
def subset(d, keys):
# Version which raises if any of the keys are missing
return {key: d[key] for key in keys}
--
Steve
More information about the Python-ideas
mailing list