'Create a Python dictionary containing specific key–value pairs from another dictionary [duplicate]
I have some code that looks something like this:
d = {'foo': True, 'bar': 42, 'baz': '!'}
a = {'foo': d['foo'], 'bar': d['bar']}
b = {'foo': d['foo'], 'baz': d['baz']}
c = {'bar': d['bar'], 'baz': d['baz']}
Surely there's a better way to express this. I actually read the docs in the hope that a dictionary's copy method accepts keys to be included in the new dictionary:
# I'd hoped that something like this would work...
a = d.copy('foo', 'bar')
b = d.copy('foo', 'baz')
c = d.copy('bar', 'baz')
I could write a function for this purpose:
copydict = lambda dct, *keys: {key: dct[key] for key in keys}
a = copydict(d, 'foo', 'bar')
b = copydict(d, 'foo', 'baz')
c = copydict(d, 'bar', 'baz')
Is there a better solution than the above?
Solution 1:[1]
I guess that the function in the question is the best solution.
Of course, someone could post some idiomatic code, but I'm sure it wouldn't work better/faster. Iterating over a list and getting items from a dict by key is as fast as it can get.
One suggestion is to remove the star from the keys parameter. Argument unpacking adds unnecessary overhead. There should be no problem with just passing those keys as a tuple.
Solution 2:[2]
The only improvement I would make is to use a real function definition, not a lambda:
def copy_dict(d, *keys):
"""Make a copy of only the `keys` from dictionary `d`."""
return {key: d[key] for key in keys}
It could be useful to deal with missing keys, but in Python 2 you can't mix optional keyword arguments with *args nicely, so you might have to go to a tuple argument:
def copy_dict(d, keys, default=None):
"""Make a copy of only the `keys` from dictionary `d`.
Use `default` if a key is missing.
"""
return {key: d.get(key, default) for key in keys}
Solution 3:[3]
As pointed out by @BlaXpirit, this solution probably isn't going to be better than yours in terms of speed or readability, but you could do something like this:
>>> from operator import itemgetter
>>> d = {'foo': True, 'bar': 42, 'baz': '!'}
>>> keys = ['foo', 'bar']
>>> dict(zip(keys, itemgetter(*keys)(d)))
{'bar': 42, 'foo': True}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Oleh Prypin |
| Solution 2 | Ned Batchelder |
| Solution 3 | jcollado |
