当前位置: 首页 > news >正文

Python Cookbook-4.13 获取字典的一个子集

任务

你有一个巨大的字典,字典中的一些键属于一个特定的集合,而你想创建一个包含这个键集合及其对应值的新字典。

解决方案

如果你不想改动原字典:

def sub_dict(somedict,somekeys,default = None):
	return dict([(k, somedict.get(k,default)) for k in somekeys ])

如果你从原字典中删除那些符合条件的条目:

def sub_dict_remove(somedict,somekeys,default = None):
	return dict([ (k, somedict.pop(k,default)) for k in somekeys ])

下面是两个函数的使用和效果:

>>>d = {'a':5,'b':6,'c':7}
>>>print sub_dict(d,'ab'),d
{'a':5,'b':6}{'a':5,'b':6,'c': 7}
>>> print sub_dict_remove(d,'ab'),d
{'a':5,'b':6}{'c':7}

讨论

在 Python 中,我在很多地方都用到了字典——数据库的行、主键和复合键,用于模板解析的变量名字空间等。我常常需要基于另外一个已有的大字典创建一个新字典,此字典的键是大字典的键的一个子集。在大多数情况下,原字典应该保持不变;但有时,我也需要在完成了抽取之后删除在原字典中的子集。本节的解决方案对两种可能性都给出了答案。区别仅仅在于,如果需要原字典保持原样不变,使用get方法,如果需要删除子集,则使用 pop 方法。

如果 somekeys 中的某元素k并不是 somedict的键,解决方案提供的函数会将k作为结果的键,并对应一个默认值(可以作为一个可选的参数传递给这两个函数,默认情况下是 None)。所以,最终结果也不一定是somedict 的子集。不过我却发现这种行为方式对我的应用非常有帮助。

当你认为 somekeys中的所有的元素都应当是 somedict 的键时,也许会希望在键“缺失的时候获得一个异常,它可以提示和警告你程序中的bug。记住,Tim Peters 在 The Zeno/Python 中说过“错误不应该被静静地略过,除非有意为之”(在 Python 的交互式解释器的提示符下敲入 import this 并回车,你将看到精炼的 Python 设计原则)。所以,如果从你的应用的角度看,键不匹配是一个错误,那么会希望马上得到一个异常来提醒你错误的发生。如果这的确是你所希望的,可以对解决方案中的函数略作修改:

def sub_dict_strict(somedict,somekeys):
	return dict([ (k,somedict[k]) for k in somekeys ])
def sub_dict_remove_strict(somedict,somekeys):
	return dict([ (k,somedict.pop(k)) for k in somekeys ])

这些更加严格的变体版本甚至比原版本更简单——这充分说明了Python 本来就喜欢在意外发生时抛出异常。
或者,你希望在键不匹配时直接将其忽略。这也只需要一点点修改:

def sub_dict_select(somedict,somekeys):
	return dict([ (k,somedict[k[) for k in somekeys if k in somedict])
def sub_dict_remove_select(somedict,somekeys):
	return dict([ (k,somedict,pop(k)) for k in somekeys if k in somedict))

列表推导中的if子句做完了我们期望的事,即在应用k之前先做鉴别工作。

在 Python 2.4中可以用生成器表达式来替代列表推导,用它作为本节中的函数的参数。我们只需略微修改 dict 的调用,将 dict([…])改成 dict(…)(移除临近圆括号的方括号),就能享受进一步的简化和速度的提升。不过这些修改不适用 Python2.3,因为它只支持列表推导而不支持生成器表达式。

相关文章:

  • 19.OpenCV图像二值化
  • 【Linux笔记】进程间通信——命名管道
  • 深度学习中的数据类型
  • 17-动规-最长增长子序列
  • leetcode90-子集II
  • 我的编程之旅:从零到无限可能
  • 剖析 Redis 缓存更新策略:保障数据一致性与系统性能的平衡
  • 光传输设备现状
  • 刷题日记day14-字符串-数组去重和排序
  • flutter 专题 七十四 Flutter开发之动画
  • 【Docker镜像】Python项目之使用Dockerfile构建镜像(二)
  • 在Trae中设置Python解释器版本
  • 从零实现3D自动标注:MS3D、MS3D++
  • Android 项目问题:The specified Android SDK Build Tools version (28.0.3) is ignored
  • 【SMBIOS数据块类型列表】
  • 精心整理-2024最新网络安全-信息安全全套资料(学习路线、教程笔记、工具软件、面试文档).zip
  • SQL Server:当在删除数据库时因为存在触发器而无法删除
  • 中小型企业网络的搭建
  • c++学习系列----006. c++模板(函数模板)
  • 静态网页应用开发环境搭建实战教程
  • 俄伏尔加格勒机场正式更名为斯大林格勒机场
  • 启程回家!神十九轨道舱与返回舱成功分离
  • 媒体:黑话烂梗包围小学生,“有话好好说”很难吗?
  • 直播电商行业代表呼吁:携手并肩伸出援手助力外贸企业攻坚克难
  • 国务院任免国家工作人员:饶权任国家文物局局长
  • 商务部:4月份以来的出口总体延续平稳增长态势