我有一个字典,里面有一大堆词条。我只对其中的几个感兴趣。有什么简单的方法可以把其他的都剪掉吗?
当前回答
这个函数可以做到:
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版本不同的是,该操作不是在适当的位置完成的,因此性能与字典中的键数有关。但是,这样做的好处是该函数不会修改所提供的字典。
编辑:添加了一个单独的功能,用于从字典中排除某些键。
其他回答
下面是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的答案要慢。
你可以用我的函数库中的项目函数来做:
from funcy import project
small_dict = project(big_dict, keys)
还要看一下select_keys。
这个函数可以做到:
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版本不同的是,该操作不是在适当的位置完成的,因此性能与字典中的键数有关。但是,这样做的好处是该函数不会修改所提供的字典。
编辑:添加了一个单独的功能,用于从字典中排除某些键。
根据问题的标题,人们会期望在适当的地方过滤字典-几个答案建议了这样做的方法-仍然不明显的一个明显的方法是什么-我添加了一些时间:
import random
import timeit
import collections
repeat = 3
numbers = 10000
setup = ''
def timer(statement, msg='', _setup=None):
print(msg, min(
timeit.Timer(statement, setup=_setup or setup).repeat(
repeat, numbers)))
timer('pass', 'Empty statement')
dsize = 1000
d = dict.fromkeys(range(dsize))
keep_keys = set(random.sample(range(dsize), 500))
drop_keys = set(random.sample(range(dsize), 500))
def _time_filter_dict():
"""filter a dict"""
global setup
setup = r"""from __main__ import dsize, collections, drop_keys, \
keep_keys, random"""
timer('d = dict.fromkeys(range(dsize));'
'collections.deque((d.pop(k) for k in drop_keys), maxlen=0)',
"pop inplace - exhaust iterator")
timer('d = dict.fromkeys(range(dsize));'
'drop_keys = [k for k in d if k not in keep_keys];'
'collections.deque('
'(d.pop(k) for k in list(d) if k not in keep_keys), maxlen=0)',
"pop inplace - exhaust iterator (drop_keys)")
timer('d = dict.fromkeys(range(dsize));'
'list(d.pop(k) for k in drop_keys)',
"pop inplace - create list")
timer('d = dict.fromkeys(range(dsize));'
'drop_keys = [k for k in d if k not in keep_keys];'
'list(d.pop(k) for k in drop_keys)',
"pop inplace - create list (drop_keys)")
timer('d = dict.fromkeys(range(dsize))\n'
'for k in drop_keys: del d[k]', "del inplace")
timer('d = dict.fromkeys(range(dsize));'
'drop_keys = [k for k in d if k not in keep_keys]\n'
'for k in drop_keys: del d[k]', "del inplace (drop_keys)")
timer("""d = dict.fromkeys(range(dsize))
{k:v for k,v in d.items() if k in keep_keys}""", "copy dict comprehension")
timer("""keep_keys=random.sample(range(dsize), 5)
d = dict.fromkeys(range(dsize))
{k:v for k,v in d.items() if k in keep_keys}""",
"copy dict comprehension - small keep_keys")
if __name__ == '__main__':
_time_filter_dict()
结果:
Empty statement 8.375600000000427e-05
pop inplace - exhaust iterator 1.046749841
pop inplace - exhaust iterator (drop_keys) 1.830537424
pop inplace - create list 1.1531293939999987
pop inplace - create list (drop_keys) 1.4512304149999995
del inplace 0.8008298079999996
del inplace (drop_keys) 1.1573763689999979
copy dict comprehension 1.1982901489999982
copy dict comprehension - small keep_keys 1.4407784069999998
因此,如果我们想要在适当的地方更新,似乎del是赢家-字典理解解决方案取决于正在创建的字典的大小,当然,删除一半的键已经太慢了-所以避免创建一个新的字典,如果你可以在适当的地方过滤。
编辑来解决@mpen的评论-我从keep_keys中计算了drop key(假设我们没有drop key) -我假设keep_keys/drop_keys是这个迭代的集合,或者会花很长时间。有了这些假设,del仍然更快——但要确定的是:如果你有一个(set, list, tuple)的下拉键,使用del
这是我的方法,支持嵌套字段,如mongo查询。
使用方法:
>>> obj = { "a":1, "b":{"c":2,"d":3}}
>>> only(obj,["a","b.c"])
{'a': 1, 'b': {'c': 2}}
只有函数:
def only(object,keys):
obj = {}
for path in keys:
paths = path.split(".")
rec=''
origin = object
target = obj
for key in paths:
rec += key
if key in target:
target = target[key]
origin = origin[key]
rec += '.'
continue
if key in origin:
if rec == path:
target[key] = origin[key]
else:
target[key] = {}
target = target[key]
origin = origin[key]
rec += '.'
else:
target[key] = None
break
return obj
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用pip3安装包时,“Python中的ssl模块不可用”
- 无法切换Python与pyenv
- Python if not == vs if !=
- 如何从scikit-learn决策树中提取决策规则?
- 为什么在Mac OS X v10.9 (Mavericks)的终端中apt-get功能不起作用?
- 将旋转的xtick标签与各自的xtick对齐
- 为什么元组可以包含可变项?
- 如何合并字典的字典?
- 如何创建类属性?
- 不区分大小写的“in”
- 在Python中获取迭代器中的元素个数
- 解析日期字符串并更改格式
- 使用try和。Python中的if
- 如何在Python中获得所有直接子目录