python - 过滤器dict只包含某些键?
我有一个dict,有一大堆条目。 我只对他们中的一小部分感兴趣。 是否有一种简单的方法可以修剪所有其他的?
mpen asked 2019-02-04T04:25:39Z
11个解决方案
441 votes
构建一个新的词典:
dict_you_want = { your_key: old_dict[your_key] for your_key in your_keys }
使用字典理解。
如果您使用缺少它们的版本(即Python 2.6及更早版本),请将其设为old_dict。虽然更加丑陋,但它是一样的。
请注意,与jnnnnn的版本不同,它具有任何大小的old_dicts的稳定性能(仅取决于your_keys的数量)。 无论是在速度还是内存方面。 由于这是一个生成器表达式,它一次处理一个项目,并且它不会查看old_dict的所有项目。
就地删除所有内容:
unwanted = set(keys) - set(your_dict)
for unwanted_key in unwanted: del your_dict[unwanted_key]
Community answered 2019-02-04T04:26:13Z
62 votes
这是python 2.6中的一个例子:
>>> a = {1:1, 2:2, 3:3}
>>> dict((key,value) for key, value in a.iteritems() if key == 1)
{1: 1}
过滤部分是if语句。
如果您只想选择一些非常多的键,这种方法比delnan的答案要慢。
jnnnnn answered 2019-02-04T04:26:50Z
60 votes
略微优雅的词典理解:
foodict = {k: v for k, v in mydict.items() if k.startswith('foo')}
ransford answered 2019-02-04T04:27:12Z
18 votes
您可以使用我的funcy库中的项目功能执行此操作:
from funcy import project
small_dict = project(big_dict, keys)
另请查看select_keys。
Suor answered 2019-02-04T04:27:40Z
15 votes
这个衬里lambda应该工作:
dictfilt = lambda x, y: dict([ (i,x[i]) for i in x if i in set(y) ])
这是一个例子:
my_dict = {"a":1,"b":2,"c":3,"d":4}
wanted_keys = ("c","d")
# run it
In [10]: dictfilt(my_dict, wanted_keys)
Out[10]: {'c': 3, 'd': 4}
这是一个基本的列表理解,迭代你的dict键(我在x中)并输出一个元组(键,值)对的列表,如果键存在于你想要的键列表中(y)。 dict()将整个事物包装为输出为dict对象。
Jim answered 2019-02-04T04:28:10Z
13 votes
给你的原始词典keys和你感兴趣的条目keys:
filtered = dict(zip(keys, [orig[k] for k in keys]))
这不如delnan的答案那么好,但应该适用于每个感兴趣的Python版本。 但是,对于原始字典中存在的keys的每个元素,它都是脆弱的。
Kai answered 2019-02-04T04:28:39Z
10 votes
代码1:
dict = { key: key * 10 for key in range(0, 100) }
d1 = {}
for key, value in dict.items():
if key % 2 == 0:
d1[key] = value
代码2:
dict = { key: key * 10 for key in range(0, 100) }
d2 = {key: value for key, value in dict.items() if key % 2 == 0}
代码3:
dict = { key: key * 10 for key in range(0, 100) }
d3 = { key: dict[key] for key in dict.keys() if key % 2 == 0}
使用number = 1000,使用timeit测量所有代码性能,并为每段代码收集1000次。
对于python 3.6,三种过滤器dict键的性能几乎相同。 对于python 2.7代码3稍微快一些。
Y.Y answered 2019-02-04T04:29:28Z
6 votes
根据德尔南接受的答案。
如果你想要的一个键不在old_dict中怎么办? delnan解决方案将抛出您可以捕获的KeyError异常。 如果这不是你需要的,也许你想:
只包括old_dict和你想要的密钥集中都存在的密钥。
default = None
new_dict = {k: old_dict[k] if k in old_dict else default for k in wanted_keys}
>>> new_dict
{'age': None, 'name': 'Foobar'}
具有未在old_dict中设置的键的默认值。
default = None
new_dict = {k: old_dict[k] if k in old_dict else default for k in wanted_keys}
>>> new_dict
{'age': None, 'name': 'Foobar'}
MyGGaN answered 2019-02-04T04:30:18Z
5 votes
这个功能可以解决这个问题:
def include_keys(dictionary, keys):
"""Filters a dict by only including certain keys."""
key_set = set(keys) & set(dictionary.keys())
return {key: dictionary[key] for key in key_set}
就像delnan的版本一样,这个版本使用字典理解并且对大型字典具有稳定的性能(仅取决于您允许的密钥数量,而不是字典中的密钥总数)。
就像MyGGan的版本一样,这个版本允许您的密钥列表包含字典中可能不存在的密钥。
作为奖励,这里是反向,您可以通过排除原始中的某些键来创建字典:
def exclude_keys(dictionary, keys):
"""Filters a dict by excluding certain keys."""
key_set = set(dictionary.keys()) - set(keys)
return {key: dictionary[key] for key in key_set}
请注意,与delnan的版本不同,操作不会就位,因此性能与字典中的键数相关。 但是,这样做的好处是该函数不会修改所提供的字典。
编辑:添加了一个单独的函数,用于从dict中排除某些键。
Ryan answered 2019-02-04T04:31:12Z
1 votes
简写:
[s.pop(k) for k in list(s.keys()) if k not in keep]
由于大多数答案建议为了保持简洁,我们必须创建一个重复的对象,如list或dict.这一个创建一个扔掉list但删除原始dict中的键。
nehemiah answered 2019-02-04T04:31:36Z
0 votes
另外一个选项:
content = dict(k1='foo', k2='nope', k3='bar')
selection = ['k1', 'k3']
filtered = filter(lambda i: i[0] in selection, content.items())
但是你得到了一个list(Python 2)或一个迭代器(Python 3),由filter(),而不是dict返回。
marsl answered 2019-02-04T04:32:00Z