Get a sub-set of a Python dictionary

PythonDictionary

Python Problem Overview


I have a dictionary:

{'key1':1, 'key2':2, 'key3':3}

I need to pass a sub-set of that dictionary to third-party code. It only wants a dictionary containing keys ['key1', 'key2', 'key99'] and if it gets another key (eg 'key3'), it explodes in a nasty mess. The code in question is out of my control so I'm left in a position where I have to clean my dictionary.

What's the best, way to limit a dictionary to a set of keys?

Given the example dictionary and allowed keys above, I want:

{'key1':1, 'key2':2}

Python Solutions


Solution 1 - Python

In [38]: adict={'key1':1, 'key2':2, 'key3':3}
In [41]: dict((k,adict[k]) for k in ('key1','key2','key99') if k in adict)
Out[41]: {'key1': 1, 'key2': 2}

In Python3 (or Python2.7 or later) you can do it with a dict-comprehension too:

>>> {k:adict[k] for k in ('key1','key2','key99') if k in adict}
{'key2': 2, 'key1': 1}

Solution 2 - Python

dict(filter(lambda i:i[0] in validkeys, d.iteritems()))

Solution 3 - Python

In modern Python (2.7+,3.0+), use a dictionary comprehension:

d = {'key1':1, 'key2':2, 'key3':3}
included_keys = ['key1', 'key2', 'key99']

{k:v for k,v in d.items() if k in included_keys}

Solution 4 - Python

An other solution without if in dict comprehension.

>>> a = {'key1':1, 'key2':2, 'key3':3}
>>> b = {'key1':1, 'key2':2}
>>> { k:a[k] for k in b.keys()}
{'key2': 2, 'key1': 1}

Solution 5 - Python

My way to do this is.

from operator import itemgetter

def subdict(d, ks):
    return dict(zip(ks, itemgetter(*ks)(d)))

my_dict = {'key1':1, 'key2':2, 'key3':3}

subdict(my_dict, ['key1', 'key3'])

Update

I have to admit though, the above implementation doesn't handle the case when the length of ks is 0 or 1. The following code handles the situation and it is no longer an one-liner.

def subdict(d, ks):
    vals = []
    if len(ks) >= 1:
        vals = itemgetter(*ks)(d)
        if len(ks) == 1:
            vals = [vals]
    return dict(zip(ks, vals))

Solution 6 - Python

I see you like to keep the first 2 elements of the dict, so you can do:

>>> {k:a[k] for k in list(a.keys())[:2]}
{'key1': 1, 'key2': 2}

Solution 7 - Python

With a complex class Myclass being a subclass of collections.UserDict. To select a subset of it, i.e keeping all its container properties, it's convenient to define a method, e.g. named sub like so:

def sub(self, keys):
    subset = Myclass() # no arguments; works if defined with only keyword arguments
    for key in keys:
        subset[key] = self[key]
    return subset

It is then used as Myclass.sub([key1, key2 ...])

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionOliView Question on Stackoverflow
Solution 1 - PythonunutbuView Answer on Stackoverflow
Solution 2 - PythonBjörn PollexView Answer on Stackoverflow
Solution 3 - PythonwatsonicView Answer on Stackoverflow
Solution 4 - PythonNazime LakehalView Answer on Stackoverflow
Solution 5 - PythonLei ZhaoView Answer on Stackoverflow
Solution 6 - Pythongty3310View Answer on Stackoverflow
Solution 7 - Pythontheo olsthoornView Answer on Stackoverflow