Answers:
构建一个新的字典:
dict_you_want = { your_key: old_dict[your_key] for your_key in your_keys }
使用字典理解。
如果使用缺少它们的版本(例如Python 2.6和更早版本),请使其成为dict((your_key, old_dict[your_key]) for ...)
。一样,尽管丑陋。
请注意,这与jnnnnn的版本不同,对于old_dict
任何大小的,都具有稳定的性能(仅取决于your_keys的数量)。在速度和内存方面。由于这是一个生成器表达式,因此它一次只能处理一项,并且不会浏览old_dict的所有项。
就地删除所有内容:
unwanted = set(keys) - set(your_dict)
for unwanted_key in unwanted: del your_dict[unwanted_key]
old_dict
表示其他地方存在错误,在那种情况下,我非常喜欢错误而不是默默地错误的结果。
dict理解稍微更优雅:
foodict = {k: v for k, v in mydict.items() if k.startswith('foo')}
mydict.iteritems()
改用,则可能是相同的性能。.items()
创建另一个列表。
这是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的答案要慢。
if key in ('x','y','z')
。
代码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随时间测量所有代码性能,并为每个代码收集1000次。
对于python 3.6,三种过滤器dict键的性能几乎相同。对于python 2.7,代码3稍快一些。
这一个线性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}
这是对列表键(i在x中)进行迭代的基本列表理解,如果键位于所需的键列表(y)中,则输出元组(键,值)对的列表。dict()将整个内容包装为dict对象。
set
for wanted_keys
,但是看起来不错。
dictfilt({'x':['wefwef',52],'y':['iuefiuef','efefij'],'z':['oiejf','iejf']}, ('x','z'))
,它将{'x': ['wefwef', 52], 'z': ['oiejf', 'iejf']}
按预期返回。
dict={'0':[1,3], '1':[0,2,4], '2':[1,4]}
进行了尝试,结果是{}
,我认为这是空白字典。
foo = {'0':[1,3], '1':[0,2,4], '2':[1,4]}; dictfilt(foo,('0','2'))
,我得到:{'0': [1, 3], '2': [1, 4]}
这是预期的结果
给定您的原始字典orig
和您感兴趣的条目集keys
:
filtered = dict(zip(keys, [orig[k] for k in keys]))
这不如delnan的答案那么好,但是应该可以在每个感兴趣的Python版本中使用。但是,它对于keys
原始字典中存在的每个元素都是脆弱的。
基于delnan接受的答案。
如果您想要的键之一不在old_dict中怎么办?delnan解决方案将引发您可以捕获的KeyError异常。如果那不是您所需要的,也许您想:
仅在old_dict和您的通缉钥匙组中包含存在的钥匙。
old_dict = {'name':"Foobar", 'baz':42}
wanted_keys = ['name', 'age']
new_dict = {k: old_dict[k] for k in set(wanted_keys) & set(old_dict.keys())}
>>> new_dict
{'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'}
{k: old_dict.get(k, default) for k in ...}
此功能可以解决问题:
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版本不同,该操作未在适当位置完成,因此性能与字典中键的数量有关。但是,这样做的好处是该函数不会修改提供的字典。
编辑:添加了一个单独的功能,用于从字典中排除某些键。
invert
意味着keys
参数保持,或者说keys
参数被拒绝?”,多少人会同意吗?
如果我们要删除选定的键来制作新字典,可以利用字典理解功能
,例如:
d = {
'a' : 1,
'b' : 2,
'c' : 3
}
x = {key:d[key] for key in d.keys() - {'c', 'e'}} # Python 3
y = {key:d[key] for key in set(d.keys()) - {'c', 'e'}} # Python 2.*
# x is {'a': 1, 'b': 2}
# y is {'a': 1, 'b': 2}
另外一个选项:
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
。
filtered
起来dict
,您就会得到字典!
您可以使用python-benedict
,它是dict的子类。
安装: pip install python-benedict
from benedict import benedict
dict_you_want = benedict(your_dict).subset(keys=['firstname', 'lastname', 'email'])
它在GitHub上是开源的:https : //github.com/fabiocaccamo/python-benedict
免责声明:我是这个图书馆的作者。