使用python写代码时,是否经常遇到KeyError呢?

如何定义一个多层嵌套的字典呢?当我们使用普通字典时,用法一般是a=dict(),然后可以为字典添加元素,如a['key']='xxx'.之后便可以使用a['key']引用'xxx'这个值。如果引用的Key不存在,就会抛出KeyError。如下:

>>> a=dict()>>> a[1]Traceback (most recent call last):  File "", line 1, in <module>KeyError: 1

使用defaultdict替换dict,可以避免KeyError,这可以让我们专心于代码业务逻辑,而不是检查某个key是否存在了。

defaultdict是python内建模块collections提供的一个集合类。defaultdict会在对应key不存在时返回一个默认值,除此之外与dict没有区别。

如何导入defaultdict?

要使用defaultdict,需要先导入defaultdict,如下:

from collections import defaultdict

defaultdict可接受参数有哪些?

defaultdict可接受的参数可以分为三类,先总结一下,分别为:

1

接受None作为参数。

2

接受一个‘类型’作为参数,比如int、str、list、dict等。传入类型的默认值作为返回值。

3

接受任何不带参数的可调用函数作为参数,该函数的返回结果作为默认值。

三种类型具体分析如下:01接受None作为参数

先看一段代码,示例如下:

>>> from collections import defaultdict>>> my_dict=defaultdict(None)>>> my_dict=defaultdict()

上面两种写法是一样的,传入None和不传入参数都是指没有返回值。既然没有返回值,那么此时"my_dict=defaultdict()"与"my_dict=dict()",就完全等价了。当key不存在时,也会异常:

>>> from collections import defaultdict>>> my_dict=defaultdict(None)>>> my_dict=defaultdict()>>> my_dict[1]Traceback (most recent call last):  File "", line 1, in <module>KeyError: 1

如果只是这种用法,那么一般不使用defaultdict,直接使用dict即可。

02接受一个‘类型’作为参数

接受一个‘类型’作为参数,比如int、str、list、dict等。传入类型的默认值作为返回值。比如int、str、list、dict默认值分别为0、''、[]、{},那么下面的代码分别返回对应值:

>>> from collections import defaultdict>>> my_dict=defaultdict(int)>>> my_dict[1]0>>> my_dict=defaultdict(str)>>> my_dict[1]''>>> my_dict=defaultdict(list)>>> my_dict[1][]>>> my_dict=defaultdict(dict)>>> my_dict[1]{}

int、str、list作为参数没有什么好说的,dict作为参数可以引申一下。该用法可以为多层嵌套结构定义默认值,理论上是可以嵌套无数层字典结构的,不过有个小坑。先看示例:

>>> from collections import defaultdict>>> my_dict=defaultdict(dict)>>> my_dict[1]{}>>> my_dict[1][2]Traceback (most recent call last):  File "", line 1, in <module>KeyError: 2

分析一下:my_dict=defaultdict(dict)使my_dict变为了一个有返回值的字典,即my_dict的每个key,不管存在与否都返回一个{}。但是这个返回的{}只是一个普通字典啊,所以当我们使用my_dict[1][2]时就抛异常了,因为my_dict[1]=dict()。

那么如何使my_dict[1]也变为一个具有返回值的字典呢?my_dict=defaultdict(defaultdict)?并没有这么简单,看示例:

>>> from collections import defaultdict>>>>>> my_dict=defaultdict(defaultdict)>>> my_dict[1]defaultdict(None, {})>>> my_dict[1][2]Traceback (most recent call last):  File "", line 1, in <module>KeyError: 2

怎么回事?为何报错了?懵...

分析一下,可以看到上面的代码里my_dict[1]输出的是'defaultdict(None, {})',先看一下下面的代码:

>>> from collections import defaultdict>>> my_dict=defaultdict()>>> my_dictdefaultdict(None, {})

输出的也是'defaultdict(None, {})',这怎么回事啊?

我们开始说过'my_dict=defaultdict()'和普通字典是一样的,那么'my_dict=defaultdict(defaultdict)'中的'my_dict[1]'也是普通字典咯...

为什么会这样?

因为defaultdict不支持这样的嵌套传参!

那又怎么定义更多层的具有返回值的字典呢?别急,是有方法的,使用匿名函数lambda可以实现,如下:

二层嵌套

>>> from collections import defaultdict>>> my_dict=defaultdict(lambda: defaultdict(dict))>>> my_dict[1]defaultdict(<class 'dict'>, {})>>> my_dict[1][2]{}# 第三层才会异常>>> my_dict[1][2][3]Traceback (most recent call last):  File "<stdin>", line 1, in <module>KeyError: 3

三层嵌套

>>> from collections import defaultdict>>> my_dict=defaultdict(lambda: defaultdict(lambda: defaultdict(dict)))>>> my_dict[1]defaultdict(<function <lambda>.<locals>.<lambda> at 0x00000243B13A2318>, {})>>> my_dict[1][2]defaultdict(<class 'dict'>, {})>>> my_dict[1][2][3]{}# 第四层异常>>> my_dict[1][2][3][4]Traceback (most recent call last):  File "<stdin>", line 1, in <module>KeyError: 4

五层嵌套..

六层嵌套..

由此可见无数层嵌套结构都是可以的...

当然,最后一层也不一定是dict了,int、str...所有defaultdict可接受参数都行的。

由上面这种利用lambda无线嵌套的用法,我们可以引出defaultdict的第三类可接受参数了,接着看...

03任何不带参数的可调用函数作为参数

接受任何不带参数的可调用函数作为参数,该函数的返回结果作为默认值。

直接看代码:

>>> from collections import defaultdict>>> def my_return():...     return 'my_value' # 也可以返回自定义结构,如另一个嵌套字典......>>> my_dict=defaultdict(my_return)>>> my_dict[1]'my_value'>>># 多层嵌套>>> my_dict=defaultdict(lambda: defaultdict(lambda: defaultdict(lambda: defaultdict(my_return))))>>> my_dict[1][2][3][4]'my_value'

可以看到,因为这个返回的默认值,我们可以利用defaultdict做很多事情了。各位,还有什么其他好玩的用法,欢迎留言分享!

客官,喜欢就关注一下吧

file watchers怎么默认打开_python默认字典defaultdict进阶相关推荐

  1. file watchers怎么默认打开_Python读写文件怎么和我之前学的不一样?

    点击上方「蓝字」关注我们 Python中对文件的读写 读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘. 读写文件就是请求操作系统打 ...

  2. file watchers怎么默认打开_python怎么打印字符

    print() 方法用于打印输出,最常见的一个函数. 在 Python3.3 版增加了 flush 关键字参数. print 在 Python3.x 是一个函数,但在 Python2.x 版本不是一个 ...

  3. 设置eclipse文件的默认打开方式

    由于cfg.biz等配置文件默认的打开方式并不是Text Editor,打开时要手动右键"open with"来选择"Text Editor"来打开,频繁操作略 ...

  4. Eclipse设定文件的默认打开方式

    之前在eclipse中安装了androrid开发环境所有的xml打开发现下面只剩一下选择,原来maven的依赖查询都没有了. 解决方法: 1.最终解决方法 设置默认打开方式为MAVEN POM Edi ...

  5. 解决MATLAB不能设置为.m文件默认打开方式

    转载:https://blog.csdn.net/yujiaerzong/article/details/77624167 将下面代码复制保存为 associateFiles.m 文件. 或者从下面链 ...

  6. C# 设置文件默认打开程序

    C# 设置文件默认打开程序 代码片段如下 /// <summary>/// 设置文件默认打开程序 前提是程序支持参数启动打开文件/// 特殊说明:txt后缀比较特殊,还需要从注册表修改us ...

  7. Eclipse设置各类型文件默认打开方式

    如何修改Eclipse各类型文件的默认打开方式 工具/原料 Eclipse 方法/步骤 1 打开Eclipse,选择[window]-->[Preferences]打开设置 2 依次选择Gene ...

  8. 改xml文件默认打开方式

    java格式文件的代码提示功能的设置: 1. 打开Eclipse,然后"window"→"Preferences" 2. 选择"java", ...

  9. Android修改默认打开WLAN随时都可扫描

    本文基于Android5.1 frameworks/base/packages/SettingsProvider/res/values/defaults.xml 1为默认打开状态,0为默认关闭状态 & ...

  10. MTK6757 9.0 USB debugger 默认打开, 开发者选项无法打开

    一. USB debugger 默认打开 1. build\make\core\main.mk 将ro.debuggable 值改为1 ADDITIONAL_DEFAULT_PROPERTIES += ...

最新文章

  1. 《LED调光-DMX512灯光协义接收控制》转
  2. Kafka日志清理之Log Compaction
  3. 长这么大了,一件事也没做好过
  4. opencv4.10不能使用sift = cv2.xfeatures2d.SIFT_create()
  5. 徐扬:互联网营销下的移动营销
  6. 1.9_heap_topK_topK问题
  7. WITH (NOLOCK)提高查询效率
  8. kudu底层存储引擎的数据组织方式
  9. java计算机毕业设计英语学习网站设计与实现MyBatis+系统+LW文档+源码+调试部署
  10. 颠覆思维,你也能懂量子力学
  11. android属于数据库管理系统,详细谈谈Android系统中的SQLite数据库的应用
  12. win10打开蓝牙_Win10隐藏技巧:如何一键开启蓝牙功能!
  13. LeetCode 11-20 题
  14. dp专题-cf 711c
  15. IDEA 同时打开两个项目
  16. 如何确定Z检验的值(查正态分布表时要注意中间的数字都是面积,最左边一列和最上面一行都是Z值)...
  17. 2018年数学建模国赛A题题目、解题思路、matlab代码(四)
  18. 00002 贪婪洞窟.001
  19. Android 支持分屏
  20. java 鼠标单击_转:java 鼠标单击和双击的控制

热门文章

  1. PHP CURL实现远程下载文件到本地
  2. 让li不显示超出内容,显示... (编程方法和CSS方法)
  3. web安全day43:网络扫描和Nmap的使用
  4. php在windows安装,php在windows环境下的安装
  5. 明显调用的表达式前的括号必须具有(指针)函数类型
  6. H3C大规模路由综合实验
  7. CICD详解(四)——Jenkins下载与安装
  8. Linux系统如何安装不知名称的软件?
  9. QoS令牌桶技术详解
  10. uestc--758--P酱的冒险旅途