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?
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.
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}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With