Python中dict和set的用法讲解


Posted in Python onMarch 28, 2019

dict

Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。

举个例子,假设要根据同学的名字查找对应的成绩,如果用list实现,需要两个list:

names = ['Michael', 'Bob', 'Tracy']
scores = [95, 75, 85]

给定一个名字,要查找对应的成绩,就先要在names中找到对应的位置,再从scores取出对应的成绩,list越长,耗时越长。

如果用dict实现,只需要一个“名字”-“成绩”的对照表,直接根据名字查找成绩,无论这个表有多大,查找速度都不会变慢。用Python写一个dict如下:

>>> d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
>>> d['Michael']
95

为什么dict查找速度这么快?因为dict的实现原理和查字典是一样的。假设字典包含了1万个汉字,我们要查某一个字,一个办法是把字典从第一页往后翻,直到找到我们想要的字为止,这种方法就是在list中查找元素的方法,list越大,查找越慢。

第二种方法是先在字典的索引表里(比如部首表)查这个字对应的页码,然后直接翻到该页,找到这个字,无论找哪个字,这种查找速度都非常快,不会随着字典大小的增加而变慢。

dict就是第二种实现方式,给定一个名字,比如'Michael',dict在内部就可以直接计算出Michael对应的存放成绩的“页码”,也就是95这个数字存放的内存地址,直接取出来,所以速度非常快。

你可以猜到,这种key-value存储方式,在放进去的时候,必须根据key算出value的存放位置,这样,取的时候才能根据key直接拿到value。

把数据放入dict的方法,除了初始化时指定外,还可以通过key放入:

>>> d['Adam'] = 67
>>> d['Adam']
67

由于一个key只能对应一个value,所以,多次对一个key放入value,后面的值会把前面的值冲掉:

>>> d['Jack'] = 90
>>> d['Jack']
90
>>> d['Jack'] = 88
>>> d['Jack']
88

如果key不存在,dict就会报错:

>>> d['Thomas']
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
KeyError: 'Thomas'

要避免key不存在的错误,有两种办法,一是通过in判断key是否存在:

>>> 'Thomas' in d
False

二是通过dict提供的get方法,如果key不存在,可以返回None,或者自己指定的value:

>>> d.get('Thomas')
>>> d.get('Thomas', -1)
-1

注意:返回None的时候Python的交互式命令行不显示结果。

要删除一个key,用pop(key)方法,对应的value也会从dict中删除:

>>> d.pop('Bob')
75
>>> d
{'Michael': 95, 'Tracy': 85}

请务必注意,dict内部存放的顺序和key放入的顺序是没有关系的。

和list比较,dict有以下几个特点:

查找和插入的速度极快,不会随着key的增加而增加;
需要占用大量的内存,内存浪费多。
而list相反:
查找和插入的时间随着元素的增加而增加;
占用空间小,浪费内存很少。
所以,dict是用空间来换取时间的一种方法。

dict可以用在需要高速查找的很多地方,在Python代码中几乎无处不在,正确使用dict非常重要,需要牢记的第一条就是dict的key必须是不可变对象。

这是因为dict根据key来计算value的存储位置,如果每次计算相同的key得出的结果不同,那dict内部就完全混乱了。这个通过key计算位置的算法称为哈希算法(Hash)。

要保证hash的正确性,作为key的对象就不能变。在Python中,字符串、整数等都是不可变的,因此,可以放心地作为key。而list是可变的,就不能作为key:

>>> key = [1, 2, 3]
>>> d[key] = 'a list'
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

set

set和dict类似,也是一组key的集合但不存储value。由于key不能重复,所以,在set中,没有重复的key。

要创建一个set,需要提供一个list作为输入集合:

>>> s = set([1, 2, 3])
>>> s
set([1, 2, 3])

注意,传入的参数[1, 2, 3]是一个list,而显示的set([1, 2, 3])只是告诉你这个set内部有1,2,3这3个元素,显示的[]不表示这是一个list。

重复元素在set中自动被过滤:

>>> s = set([1, 1, 2, 2, 3, 3])
>>> s
set([1, 2, 3])

通过add(key)方法可以添加元素到set中,可以重复添加,但不会有效果:

>>> s.add(4)
>>> s
set([1, 2, 3, 4])
>>> s.add(4)
>>> s
set([1, 2, 3, 4])

通过remove(key)方法可以删除元素:

>>> s.remove(4)
>>> s
set([1, 2, 3])

set可以看成数学意义上的无序和无重复元素的集合,因此,两个set可以做数学意义上的交集、并集等操作:

>>> s1 = set([1, 2, 3])
>>> s2 = set([2, 3, 4])
>>> s1 & s2
set([2, 3])
>>> s1 | s2
set([1, 2, 3, 4])

set和dict的唯一区别仅在于没有存储对应的value,但是,set的原理和dict一样,所以,同样不可以放入可变对象,因为无法判断两个可变对象是否相等,也就无法保证set内部“不会有重复元素”。试试把list放入set,看看是否会报错。

再议不可变对象

上面我们讲了,str是不变对象,而list是可变对象。

对于可变对象,比如list,对list进行操作,list内部的内容是会变化的,比如:

>>> a = ['c', 'b', 'a']
>>> a.sort()
>>> a
['a', 'b', 'c']

而对于不可变对象,比如str,对str进行操作呢:

>>> a = 'abc'
>>> a.replace('a', 'A')
'Abc'
>>> a
'abc'

虽然字符串有个replace()方法,也确实变出了'Abc',但变量a最后仍是'abc',应该怎么理解呢?

我们先把代码改成下面这样:

>>> a = 'abc'
>>> b = a.replace('a', 'A')
>>> b
'Abc'
>>> a
'abc'

要始终牢记的是,a是变量,而'abc'才是字符串对象!有些时候,我们经常说,对象a的内容是'abc',但其实是指,a本身是一个变量,它指向的对象的内容才是'abc':

Python中dict和set的用法讲解

当我们调用a.replace(‘a', ‘A')时,实际上调用方法replace是作用在字符串对象'abc'上的,而这个方法虽然名字叫replace,但却没有改变字符串'abc'的内容。相反,replace方法创建了一个新字符串'Abc'并返回,如果我们用变量b指向该新字符串,就容易理解了,变量a仍指向原有的字符串'abc',但变量b却指向新字符串'Abc'了:

Python中dict和set的用法讲解

所以,对于不变对象来说,调用对象自身的任意方法,也不会改变该对象自身的内容。相反,这些方法会创建新的对象并返回,这样,就保证了不可变对象本身永远是不可变的。

使用key-value存储结构的dict在Python中非常有用,选择不可变对象作为key很重要,最常用的key是字符串。

tuple虽然是不变对象,但试试把(1, 2, 3)和(1, [2, 3])放入dict或set中,并解释结果。

>>>a = ('james', 'jordan', 'kobe')
>>>b = ('james' , ['jordan', 'kobe'])
>>>dict1={a:'篮球运动员'}
>>>dict1[a]
>>>'篮球运动员'
>>>dict2={b:'篮球运动员'}
>>>Traceback (most recent call last):
>>> File "<stdin>", line 1, in <module>
>>>TypeError: unhashable type: 'list'
#tuple a 所指向的三个人是不可变的的 他们都是篮球运动员
#tuple b 所指向的只有james是不可变的的 还有两个人虽然是叫jordan kobe但不一定就是打篮球的 可能是踢足球的jordan和打乒乓球的kobe

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。如果你想了解更多相关内容请查看下面相关链接

Python 相关文章推荐
python脚本实现统计日志文件中的ip访问次数代码分享
Aug 06 Python
从Python的源码浅要剖析Python的内存管理
Apr 16 Python
python中根据字符串调用函数的实现方法
Jun 12 Python
深入理解Python中装饰器的用法
Jun 28 Python
Python实现批量更换指定目录下文件扩展名的方法
Sep 19 Python
Python构建网页爬虫原理分析
Dec 19 Python
Numpy之random函数使用学习
Jan 29 Python
Python mutiprocessing多线程池pool操作示例
Jan 30 Python
python单例模式原理与创建方法实例分析
Oct 26 Python
利用python读取YUV文件 转RGB 8bit/10bit通用
Dec 09 Python
一文弄懂Pytorch的DataLoader, DataSet, Sampler之间的关系
Jul 03 Python
python实现局部图像放大
Nov 17 Python
python3.x实现base64加密和解密
Mar 28 #Python
python实现AES加密解密
Mar 28 #Python
详解python tkinter教程-事件绑定
Mar 28 #Python
Python中捕获键盘的方式详解
Mar 28 #Python
python sort、sort_index方法代码实例
Mar 28 #Python
详解python selenium 爬取网易云音乐歌单名
Mar 28 #Python
pyqt5利用pyqtDesigner实现登录界面
Mar 28 #Python
You might like
php自定义函数实现二维数组排序功能
2016/07/20 PHP
PHP开发之归档格式phar文件概念与用法详解【创建,使用,解包还原提取】
2017/11/17 PHP
PHP实现的字符串匹配算法示例【sunday算法】
2017/12/19 PHP
将Datatable转化成json发送前台实现思路
2013/09/06 Javascript
js实现模拟计算器退格键删除文字效果的方法
2015/05/07 Javascript
WordPress中利用AJAX异步获取评论用户头像的方法
2016/01/08 Javascript
Bootstrap基本插件学习笔记之按钮(21)
2016/12/08 Javascript
bootstrap侧边栏圆点导航
2017/01/11 Javascript
jquery实现input框获取焦点的方法
2017/02/06 Javascript
页面间固定参数,通过cookie传值的实现方法
2017/05/31 Javascript
vue.js中npm安装教程图解
2018/04/10 Javascript
自己动手封装一个React Native多级联动
2018/09/19 Javascript
BootStrap modal实现拖拽功能
2018/12/01 Javascript
Vue Router history模式的配置方法及其原理
2019/05/30 Javascript
[49:41]NB vs NAVI Supermajor小组赛A组 BO3 第一场 6.2
2018/06/03 DOTA
详解Python的Django框架中的模版相关知识
2015/07/15 Python
在DigitalOcean的服务器上部署flaskblog应用
2015/12/19 Python
Mac 上切换Python多版本
2017/06/17 Python
在Python中执行系统命令的方法示例详解
2017/09/14 Python
python实现K最近邻算法
2018/01/29 Python
python自动登录12306并自动点击验证码完成登录的实现源代码
2018/04/25 Python
pyqt5利用pyqtDesigner实现登录界面
2019/03/28 Python
Python实现的插入排序,冒泡排序,快速排序,选择排序算法示例
2019/05/04 Python
详解PyCharm+QTDesigner+PyUIC使用教程
2019/06/13 Python
python取余运算符知识点详解
2019/06/27 Python
Python TCP通信客户端服务端代码实例
2019/11/21 Python
Pycharm小白级简单使用教程
2020/01/08 Python
jupyter notebook tensorflow打印device信息实例
2020/04/20 Python
python如何求圆的面积
2020/07/01 Python
css3.0 图形构成实例练习一
2013/03/19 HTML / CSS
Tory Burch美国官方网站:美国时尚生活品牌
2016/08/01 全球购物
Sport-Thieme荷兰:购买体育用品
2019/08/25 全球购物
防灾减灾活动总结
2014/08/30 职场文书
教育见习报告范文
2014/11/03 职场文书
Python办公自动化之教你用Python批量识别发票并录入到Excel表格中
2021/06/26 Python
Go中使用gjson来操作JSON数据的实现
2022/08/14 Golang