Python字典的概念及常见应用实例详解


Posted in Python onOctober 30, 2019

本文实例讲述了Python字典的概念及常见应用。分享给大家供大家参考,具体如下:

字典的介绍

字典的概念

字典是“键值对”的无序可变序列,字典中的每个元素都是一个“键值对”,包含:“键
对象”和“值对象”。可以通过“键对象”实现快速获取、删除、更新对应的“值对象”。
列表中我们通过“下标数字”找到对应的对象。字典中通过“键对象”找到对应的“值
对象”。“键”是任意的不可变数据,比如:整数、浮点数、字符串、元组。但是:列表、
字典、集合这些可变对象,不能作为“键”。并且“键”不可重复。
“值”可以是任意的数据,并且可重复。
一个典型的字典的定义方式:

a = {'name':'gaoqi','age':18,'job':'programmer'}

字典的创建

1. 我们可以通过{}、dict()来创建字典对象。

>>> a = {'name':'gaoqi','age':18,'job':'programmer'}
>>> b = dict(name='gaoqi',age=18,job='programmer')
>>> a = dict([("name","gaoqi"),("age",18)])
>>> c = {} #空的字典对象
>>> d = dict() #空的字典对象

2. 通过 zip()创建字典对象

>>> k = ['name','age','job']
>>> v = ['gaoqi',18,'techer']
>>> d = dict(zip(k,v))
>>> d
{'name': 'gaoqi', 'age': 18, 'job': 'techer'}

3. 通过 fromkeys 创建值为空的字典

>>> a = dict.fromkeys(['name','age','job'])
>>> a
{'name': None, 'age': None, 'job': None}

字典元素的访问

为了测试各种访问方法,我们这里设定一个字典对象:

a = {'name':'gaoqi','age':18,'job':'programmer'}

1. 通过 [键] 获得“值”。若键不存在,则抛出异常。

>>> a = {'name':'gaoqi','age':18,'job':'programmer'}
>>> a['name']
'gaoqi'
>>> a['age']
18
>>> a['sex']
Traceback (most recent call last):
File "<pyshell#374>", line 1, in <module>
a['sex']
KeyError: 'sex'

2. 通过 get()方法获得“值”。推荐使用。优点是:指定键不存在,返回 None;也可以设

定指定键不存在时默认返回的对象。推荐使用 get()获取“值对象”。

>>> a.get('name')
'gaoqi'
>>> a.get('sex')
>>> a.get('sex','一个男人')
'一个男人'

3. 列出所有的键值对

>>> a.items()
dict_items([('name', 'gaoqi'), ('age', 18), ('job', 'programmer')])

4. 列出所有的键,列出所有的值

>>> a.keys()
dict_keys(['name', 'age', 'job'])
>>> a.values()
dict_values(['gaoqi', 18, 'programmer'])

5. len() 键值对的个数

6. 检测一个“键”是否在字典中

>>> a = {"name":"gaoqi","age":18}
>>> "name" in a
True

字典元素添加、修改、删除

1. 给字典新增“键值对”

如果“键”已经存在,则覆盖旧的键值对;如果“键”不存在,则新增“键值对”。

>>>a = {'name':'gaoqi','age':18,'job':'programmer'}
>>> a['address']='西三旗 1 号院'
>>> a['age']=16
>>> a
{'name': 'gaoqi', 'age': 16, 'job': 'programmer', 'address': '西三旗 1 号院'}

2. 使用 update()

将新字典中所有键值对全部添加到旧字典对象上。如果 key 有重复,则直接覆盖。

>>> a = {'name':'gaoqi','age':18,'job':'programmer'}
>>> b = {'name':'gaoxixi','money':1000,'sex':'男的'}
>>> a.update(b)
>>> a
{'name': 'gaoxixi', 'age': 18, 'job': 'programmer', 'money': 1000, 'sex': '男的'}

3. 字典中元素的删除

可以使用 del()方法;或者 clear()删除所有键值对;pop()删除指定键值对,并返回对应的“值对象”;

>>> a = {'name':'gaoqi','age':18,'job':'programmer'}
>>> del(a['name'])
>>> a
{'age': 18, 'job': 'programmer'}
>>> b = a.pop('age')
>>> b
18

4. popitem()

随机删除和返回该键值对。字典是“无序可变序列”,因此没有第一个元
素、最后一个元素的概念;popitem 弹出随机的项,因为字典并没有"最后的元素"或者其
他有关顺序的概念。若想一个接一个地移除并处理项,这个方法就非常有效(因为不用首先
获取键的列表)。

>>> a = {'name':'gaoqi','age':18,'job':'programmer'}
>>> a.popitem()
('job', 'programmer')
>>> a
{'name': 'gaoqi', 'age': 18}
>>> a.popitem()
('age', 18)
>>> a
{'name': 'gaoqi'}

序列解包

序列解包可以用于元组、列表、字典。

序列解包可以让我们方便的对多个变量赋值。

>>> x,y,z=(20,30,10)
>>> x
20
>>> y
30
>>> z
10
>>> (a,b,c)=(9,8,10)
>>> a
9
>>> [a,b,c]=[10,20,30]
>>> a
10
>>> b
20

序列解包用于字典时

默认是对“键”进行操作; 如果需要对键值对操作,则需要使用items();如果需要对“值”进行操作,则需要使用 values();

>>> s = {'name':'gaoqi','age':18,'job':'teacher'}
>>> name,age,job=s #默认对键进行操作
>>> name
'name'
>>> name,age,job=s.items() #对键值对进行操作
>>> name
('name', 'gaoqi')
>>> name,age,job=s.values() #对值进行操作
>>> name
'gaoqi'

表格数据使用字典和列表存储,并实现访问

姓名 年龄 薪资 城市
高小一 18 30000 北京
高小二 19 20000 上海
高小五 20 10000 深圳

源代码(mypy_09.py):

r1 = {"name":"高小一","age":18,"salary":30000,"city":"北京"}
r2 = {"name":"高小二","age":19,"salary":20000,"city":"上海"}
r3 = {"name":"高小五","age":20,"salary":10000,"city":"深圳"}
tb = [r1,r2,r3]
#获得第二行的人的薪资
print(tb[1].get("salary"))
#打印表中所有的的薪资
for i in range(len(tb)): # i -->0,1,2
print(tb[i].get("salary"))
#打印表的所有数据
for i in range(len(tb)):
print(tb[i].get("name"),tb[i].get("age"),tb[i].get("salary"),tb[i].get("city"))

字典核心底层原理(重要)

字典对象的核心是散列表。散列表是一个稀疏数组(总是有空白元素的数组),数组的
每个单元叫做 bucket。每个 bucket 有两部分:一个是键对象的引用,一个是值对象的引
用。
由于,所有 bucket 结构和大小一致,我们可以通过偏移量来读取指定 bucket。
Python字典的概念及常见应用实例详解

将一个键值对放进字典的底层过程

>>> a = {}
>>>
a["name"]="gaoqi"

假设字典 a 对象创建完后,数组长度为 8:
Python字典的概念及常见应用实例详解
我们要把”name”=”gaoqi”这个键值对放到字典对象 a 中,首先第一步需要计算
键”name”的散列值。Python 中可以通过 hash()来计算。

>>> bin(hash("name"))
'-0b1010111101001110110101100100101'

由于数组长度为 8,我们可以拿计算出的散列值的最右边 3 位数字作为偏移量,即
“101”,十进制是数字 5。我们查看偏移量 5,对应的 bucket 是否为空。如果为空,则
将键值对放进去。如果不为空,则依次取右边 3 位作为偏移量,即“100”,十进制是数字
4。再查看偏移量为 4 的 bucket 是否为空。直到找到为空的 bucket 将键值对放进去。流
程图如下:

Python字典的概念及常见应用实例详解

扩容

python 会根据散列表的拥挤程度扩容。“扩容”指的是:创造更大的数组,将原有内容
拷贝到新数组中。
接近 2/3 时,数组就会扩容。

根据键查找“键值对”的底层过程

我们明白了,一个键值对是如何存储到数组中的,根据键对象取到值对象,理解起来就
简单了。

>>> a.get("name")
'gaoqi'

当我们调用 a.get(“name”),就是根据键“name”查找到“键值对”,从而找到值
对象“gaoqi”。
第一步,我们仍然要计算“name”对象的散列值:

>>> bin(hash("name"))
'-0b1010111101001110110101100100101'

和存储的底层流程算法一致,也是依次取散列值的不同位置的数字。 假设数组长度为
8,我们可以拿计算出的散列值的最右边 3 位数字作为偏移量,即“101”,十进制是数字
5。我们查看偏移量 5,对应的 bucket 是否为空。如果为空,则返回 None。如果不为空,
则将这个 bucket 的键对象计算对应散列值,和我们的散列值进行比较,如果相等。则将对
应“值对象”返回。如果不相等,则再依次取其他几位数字,重新计算偏移量。依次取完后,
仍然没有找到。则返回 None。流程图如下:
Python字典的概念及常见应用实例详解

用法总结:

  1. 键必须可散列
    (1) 数字、字符串、元组,都是可散列的。
    (2) 自定义对象需要支持下面三点:
    • 支持 hash()函数
    • 支持通过__eq__()方法检测相等性。
    • 若 a==b 为真,则 hash(a)==hash(b)也为真。
  2. 字典在内存中开销巨大,典型的空间换时间。
  3. 键查询速度很快
  4. 往字典里面添加新建可能导致扩容,导致散列表中键的次序变化。因此,不要在遍历字典的同时进行字典的修改。

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
Python中正则表达式的用法实例汇总
Aug 18 Python
python实现类的静态变量用法实例
May 08 Python
Python3中关于cookie的创建与保存
Oct 21 Python
python之cv2与图像的载入、显示和保存实例
Dec 05 Python
使用python3调用wxpy模块监控linux日志并定时发送消息给群组或好友
Jun 05 Python
python 弹窗提示警告框MessageBox的实例
Jun 18 Python
python3.6环境安装+pip环境配置教程图文详解
Jun 20 Python
Python 控制终端输出文字的实例
Jul 12 Python
python基础 range的用法解析
Aug 23 Python
基于Python共轭梯度法与最速下降法之间的对比
Apr 02 Python
哈工大自然语言处理工具箱之ltp在windows10下的安装使用教程
May 07 Python
深入理解python多线程编程
Apr 18 Python
Python集合基本概念与相关操作实例分析
Oct 30 #Python
python opencv将表格图片按照表格框线分割和识别
Oct 30 #Python
python 使用pygame工具包实现贪吃蛇游戏(多彩版)
Oct 30 #Python
python常见字符串处理函数与用法汇总
Oct 30 #Python
pygame库实现俄罗斯方块小游戏
Oct 29 #Python
pygame实现俄罗斯方块游戏(对战篇1)
Oct 29 #Python
Numpy中对向量、矩阵的使用详解
Oct 29 #Python
You might like
php 3行代码的分页算法(求起始页和结束页)
2009/10/21 PHP
PHP Memcached应用实现代码
2010/02/08 PHP
php中时间轴开发(刚刚、5分钟前、昨天10:23等)
2011/10/03 PHP
自己写了一个php检测文件编码的函数
2014/04/21 PHP
php面向对象与面向过程两种方法给图片添加文字水印
2015/08/26 PHP
PHP实现的蚂蚁爬杆路径算法代码
2015/12/03 PHP
PHP常用技巧汇总
2016/03/04 PHP
PHP HTTP 认证实例详解
2016/11/03 PHP
在b/s开发中经常用到的javaScript技术
2006/08/23 Javascript
javascript 不间断的图片滚动并可点击
2010/01/15 Javascript
JavaScript 联动的无限级封装类,数据采用非Ajax方式,随意添加联动
2010/06/29 Javascript
javascript获取当前鼠标坐标的方法
2015/01/10 Javascript
Web表单提交之disabled问题js解决方法
2015/01/13 Javascript
javascript实现10个球随机运动、碰撞实例详解
2015/07/08 Javascript
jQuery中选择器的基础使用教程
2016/05/23 Javascript
ES6新特性之数组、Math和扩展操作符用法示例
2017/04/01 Javascript
js中apply和Math.max()函数的问题及区别介绍
2018/03/27 Javascript
通过vue-cli3构建一个SSR应用程序的方法
2018/09/13 Javascript
koa2 数据api中间件设计模型的实现方法
2020/07/13 Javascript
详解Howler.js Web音频播放终极解决方案
2020/08/23 Javascript
vue中解决chrome浏览器自动播放音频和MP3语音打包到线上的实现方法
2020/10/09 Javascript
Python语言的面相对象编程方式初步学习
2016/03/12 Python
一个基于flask的web应用诞生 组织结构调整(7)
2017/04/11 Python
python自动发送邮件脚本
2018/06/20 Python
python中计算一个列表中连续相同的元素个数方法
2018/06/29 Python
python中sys.argv函数精简概括
2018/07/08 Python
Pandas数据离散化原理及实例解析
2019/11/16 Python
Python 剪绳子的多种思路实现(动态规划和贪心)
2020/02/24 Python
北美领先的智能产品购物网站:Wellbots
2018/06/11 全球购物
环境科学专业个人求职信
2013/12/15 职场文书
家长对孩子评语
2014/01/30 职场文书
询价采购方案
2014/06/09 职场文书
关于爱国的标语
2014/06/24 职场文书
汽车转让协议书
2015/01/29 职场文书
vue中使用mockjs配置和使用方式
2022/04/06 Vue.js
Docker安装MySql8并远程访问的实现
2022/07/07 Servers