根据键列表将一个 dict 的一部分复制到一个新的 dict

fdm*_*ion 1 python dictionary

样本:

d = {
    "test": 1,
    "sample": 2,
    "example": 3,
    "product": 4,
    "software": 5,
    "demo": 6,
}

filter_keys = ["test","sample","example","demo"]
Run Code Online (Sandbox Code Playgroud)

我想创建一个新的字典,它只包含第一个字典中键出现在列表中的那些项目。换句话说,我想要:

d2 = {
    "test": 1,
    "sample": 2,
    "example": 3,
    "demo": 6,
}
Run Code Online (Sandbox Code Playgroud)

我可以用一个循环来做到这一点:

d2 = {}
for k in d.keys():
    if (k in filter_keys): 
        d2[k] = d[k]
Run Code Online (Sandbox Code Playgroud)

但这似乎非常“非 Pythonic”。我还猜测,如果您有一个巨大的 dict,比如说 5,000 个左右的项目,与更直接的方式相比,向新 dict 不断添加新项目会很慢。

此外,您还希望能够处理错误。如果列表包含不是字典中的键的内容,则应该忽略它。或者它可能被添加到新的字典中,但值为 None。

有没有更好的方法来实现这一点?

EML*_*EML 5

一个直接的方法是使用“字典理解”:

filtered_dict = {key: value for key, value in d.items() if key in filter_keys}
Run Code Online (Sandbox Code Playgroud)

请注意,如果条件出现在推导式的末尾,它会过滤循环语句的执行。根据字典中的键数是否大于您要过滤的键数,此修订版可能更有效:

filtered_dict = {key: d[key] for key in filter_keysif key in d}
Run Code Online (Sandbox Code Playgroud)

检查字典 ( key in d) 中的成员资格比检查过滤键列表 ( key in filter_keys)中的成员资格要快得多。但最终哪个更快取决于过滤器键列表的大小(以及在较小程度上,字典的大小)。

在没有字典理解的情况下,一种相对 python 的方法是使用dict构造函数:

filtered_dict = dict([(key, value) for key, value in d.items() if key in filter_keys])
Run Code Online (Sandbox Code Playgroud)

请注意,这本质上等同于字典理解,但如果您不熟悉字典理解语法,则可能会更清楚。