我有一本字典:
{'key1':1, 'key2':2, 'key3':3}
我需要将该字典的子集传递给第三方代码。它只需要一个包含键
['key1', 'key2', 'key99']
的字典,如果它得到另一个键(例如 'key3'
),它就会爆炸成一团糟。有问题的代码超出了我的控制范围,所以我不得不清理我的字典。
将字典限制为一组键的最佳方法是什么?
鉴于上面的示例字典和允许的键,我想要:
{'key1':1, 'key2':2}
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}
在 Python 3(或 Python 2.7 或更高版本)中,您也可以使用 dict-compressive 来完成:
>>> {k:adict[k] for k in ('key1','key2','key99') if k in adict}
{'key2': 2, 'key1': 1}
dict(filter(lambda i:i[0] in validkeys, d.items()))
在字典理解中没有 if 的另一种解决方案。
>>> a = {'key1':1, 'key2':2, 'key3':3}
>>> b = {'key1':1, 'key2':2}
>>> { k:a[k] for k in b.keys()}
{'key2': 2, 'key1': 1}
在现代 Python (2.7+,3.0+) 中,使用字典理解:
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}
我的方法是。
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'])
更新
我必须承认,上面的实现并不能处理
ks
的长度为 0 或 1 的情况。下面的代码处理了这种情况,并且它不再是单行代码了。
def subdict(d, ks):
vals = []
if len(ks) >= 1:
vals = itemgetter(*ks)(d)
if len(ks) == 1:
vals = [vals]
return dict(zip(ks, vals))
我看到你喜欢保留字典的前两个元素,所以你可以这样做:
>>> {k:a[k] for k in list(a.keys())[:2]}
{'key1': 1, 'key2': 2}
有一个复杂的类
Myclass
是 collections.UserDict
的子类。要选择它的子集,即保留其所有容器属性,可以方便地定义一个方法,例如命名为sub
,如下所示:
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
然后将其用作
Myclass.sub([key1, key2 ...]
)