本文介绍本系列教程最后一个数据结构——字典


在现实生活中,查英语字典的时候,我们通常根据单词来查找意思。而python中的字典也是类似的,根据特定的 “键”(单词)来查找 “值”(意思)。

字典的基本使用

下面以电话簿为例,我们的电话簿记录的是电话号码。当要查找电话号码时,我们根据人名来查找其电话号码,所以人名就是字典的键,电话号码就是字典的值。假设有下面这样的人名和电话号码的电话簿:

人名=>电话
Aganzo=>1230
Jack=>0221
Lee=>1354
Emilie=>2479

创建字典

现在我们来创建一个字典来表示这个电话簿:

>>> phonebook={'Aganzo':'1230', 'Jack':'0221', 'Lee':'1354', 'Emilie':'2479'}
>>> phonebook
{'Aganzo': '1230', 'Jack': '0221', 'Lee': '1354', 'Emilie': '2479'}
>>>

从上面可以看出,创建字典的基本格式为{ 键1:值1, 键2:值2, 键3:值3 ...}。除了这种方法,我们还可以通过dict函数传递关键字参数来创建字典,像下面这样:

>>> phonebook = dict(Aganzo='1230', Jack='0221', Lee='1354', Emilie='2479') # 关键字参数就是字典的键,参数值就是字典的值
>>> phonebook
{'Aganzo': '1230', 'Jack': '0221', 'Lee': '1354', 'Emilie': '2479'}
>>>

我们常用第一种方式创建字典,第二种方式比较少用,而且第二种方式有一个缺点:因为关键字参数会变为字典的键,所以键必须符合参数的命名规则(字母或下划线_开头,其后是数字、字母或下划线)。

补充:创建空字典有两种方法,一种是直接使用{};另一种是调用dict函数时,参数留空,即dict();像键:值这样的东西叫做字典的 “项”

字典基本操作

字典的基本操作有:

先来说“查”:我们可以通过名字来查找电话簿中的电话号码,在字典中类似这样,通过“键”来查“值”,基本格式为字典[键]

>>> phonebook['Aganzo']
'1230'
>>> phonebook['Jack']
'0221'
>>> phonebook['Lily']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'Lily'
>>>

从上面的代码可以看出,我们的“电话簿”中不存在Lily的电话号码,可知,当字典中不存在要查的元素时,python会提示报错。我们可以在查之前确认字典中是否有对应的项,使用成员运算符in

>>> 'Lily' in phonebook # 不存在
False
>>> 'Jack' in phonebook # 存在
True
>>>

或者查看“电话簿”中所有人的电话号码:

>>> for key in phonebook:
... print('%s=>%s' % (key, phonebook[key]))
...
Aganzo=>1230
Jack=>0221
Lee=>1354
Emilie=>2479
>>>

再来说“改”:此时得知Lee更换了电话号码为112233,需要对电话簿进行更改,使用如下代码:

>>> phonebook['Lee'] = '112233'
>>> phonebook
{'Aganzo': '1230', 'Jack': '0221', 'Lee': '112233', 'Emilie': '2479'}
>>>

再到“增”:假设新认识了一位朋友Zieg,得到了朋友的电话号码为123456,需要在“电话簿”中新增一项,和“改”操作一样,使用赋值运算符=

>>> phonebook['Zieg'] = '123456'
>>> phonebook
{'Aganzo': '1230', 'Jack': '0221', 'Lee': '112233', 'Emilie': '2479', 'Zieg': '123456'}
>>>

最后说“删”:朋友Jack与你绝交了(世事无常╮(╯▽╰)╭),你决定删除他的联系方式,此时你狠心地运行了下面的代码:

>>> del phonebook['Jack']
>>> phonebook
{'Aganzo': '1230', 'Lee': '112233', 'Emilie': '2479', 'Zieg': '123456'}
>>>

“电话簿”中再也没有了Jack的电话号码……

小结

好了,一个简单的示例过后,相信大家能理解字典的使用方法了,让我们来一个小小的总结:

创建字典的方法:

  • 通过花括号创建 x = {键1:值1, 键2:值2, 键3:值3 ...}
  • 通过dict函数创建 x = dict(key1=value1, key2=value2, key3=value3 ...)
  • 创建空字典可以使用 x = {}x = dict()

字典的基本操作:

  • 增:x['abc'] = 123 (键'abc'不存在)
  • 删:del x['abc']
  • 改:x['abc] += 1x['abc'] = 2x['abc'] *= 10……(键'abc'存在)
  • 查:result = x['abc']print(x['abc'])……(键'abc'存在)

补充:字典的用法和列表类似,只不过列表索引元素的时候使用的是数字作键,而字典大多数时候使用字符串索引元素。


关于字典的键,还有一点是要说清楚的:前面我们使用字典的时候都是使用了字符串类型的键,可我没有说字典的键只能是字符串!

实际上,字典的键可以是任意的不可变类型,如:字符串(最常用)、元组、浮点数、整数。


字典方法

字典也是对象,和列表一样,字典也提供了一些实用的方法,下面是介绍

clear

clear方法用于清空字典中的所有项:

>>> d = {'name':'feather', 'age':18}
>>> d
{'name': 'feather', 'age': 18}
>>> d.clear()
>>> d
{}
>>>

这个方法是原地的操作,意思就是操作对象是在字典本身,这和直接将变量赋值为空字典是不一样的,从下面的例子可以看出:

>>> x = {'a':1}
>>> y = x # y变量引用的字典和x变量引用的是同一个字典
>>> x = {} # 将x变量引用改为另一个字典,这个字典是空字典
>>> x
{}
>>> y # y变量引用的字典没有被改变
{'a': 1}
>>>

copy

copy方法用于返回一个新字典,这个新字典和原来的字典拥有相同的项:

>>> x = {'name':'feather', 'blog':['https://blog.csdn.net/lonely_feather', 'https://featherl.gitee.io/']}
>>> y = x.copy()
>>> y['name'] = 'Lee'
>>> y['blog'].append('https://www.cnblogs.com/featherl/')
>>> x
{'name': 'feather', 'blog': ['https://blog.csdn.net/lonely_feather', 'https://featherl.gitee.io/', 'https://www.cnblogs.com/featherl/']}
>>> y
{'name': 'Lee', 'blog': ['https://blog.csdn.net/lonely_feather', 'https://featherl.gitee.io/', 'https://www.cnblogs.com/featherl/']}
>>>

可以看到,y字典是从x复制而来的,所以改变y字典的键为'name'的项的时候并不影响x字典,要注意的是,y['blog'].append('https://www.cnblogs.com/featherl/') 这句代码不属于修改y字典,这是修改y字典的键为'blog'的项引用的列表,而y字典和x字典的'blog'项引用的是同一个列表(因为y字典的项是从x字典中复制而来的),所以修改这个列表的时候,在x和y两个字典上都可以看到效果。

这种问题是因为copy方法是“浅复制”,copy方法仅仅把相同的值存储到了一个新的字典里,要想避免这种问题,需要使用“深复制”,可以使用copy模块的deepcopy函数来实现:

>>> from copy import deepcopy
>>> x = {'list':[1,2,3]}
>>> y = deepcopy(x)
>>> y['list'].append(4)
>>> x
{'list': [1, 2, 3]}
>>> y
{'list': [1, 2, 3, 4]}
>>>

fromkeys

fromkeys方法用给定的键创建新字典,每个键对应的默认值都为None:

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

上面代码的第一个例子中,我们创建了一个空字典,然后使用这个空字典的fromkeys方法创建了一个新字典,第二个例子中,我们直接使用dict这个类(实际上dict不是函数,是一个“类”)的fromkeys方法创建新字典。

我们还可以自己设置默认值:

>>> dict.fromkeys(['name', 'age'], '???')
{'name': '???', 'age': '???'}

get

get方法使用给定的键访问字典中的项,不过,如果字典中不存在该项时,get方法返回默认值None,而不是报错:

>>> x = {'name':'Lee'}
>>> x.get('age')
>>> print(x.get('name'))
Lee
>>> print(x.get('age'))
None

同样的,这个默认值也是可以自己设定的:

>>> x = {'name':'Lee'}
>>> x.get('age', '???')
'???'

update

update方法将一个新字典合并到当前字典,当存在相同的键,用新字典的值进行覆盖:

>>> x = {'name':'Lee'}
>>> x = {'name':'Lee', 'blog':'https://featherl.gitee.io'}
>>> y = {'name':'feather', 'age':18}
>>> x.update(y)
>>> x
{'name': 'feather', 'blog': 'https://featherl.gitee.io', 'age': 18}

pop

pop方法用来返回指定键的项,并将该项从字典中移除:

>>> x = {1:1, 2:2, 3:3}
>>> x.pop(1)
1
>>> x
{2: 2, 3: 3}

上面的例子同时也证明了字典的键不一定是字符串。

popitem

popitem方法随机挑选一个项返回,并删除这个项。字典不同于列表,字典的项是没有顺序,不同的机器或者不同版本的python,其字典存储项的顺序可能是不一样的,故popitem方法具体处理哪一项是没法预测的。

使用举例如下:

>>> x = {1:1, 2:2, 3:3}
>>> x.pop
x.pop( x.popitem(
>>> help(x.popitem) >>> x.popitem()
(3, 3)
>>> x.popitem()
(2, 2)
>>> x.popitem()
(1, 1)
>>> x.popitem()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'popitem(): dictionary is empty'

当字典为空的时候,该方法抛出错误。

items

items方法返回字典的所有的项,每个项为一个形式为(key, value)的元组,返回的类型是一种类似列表的类型,可以使用for循环迭代,但是没有列表的方法,最好先使用list转换成列表:

>>> x = {'name':'Lee', 'age':18}
>>> x.items()
dict_items([('name', 'Lee'), ('age', 18)])
>>> list(x.items()) # 转换成列表
[('name', 'Lee'), ('age', 18)]

注意:在python2中此方法还有后面的keys、values方法返回的就是列表类型,不过我们学的是python3,要注意区分。

类似items的方法还有:

  • keys方法返回字典的所有的键(类似列表的类型)
  • values方法返回字典的所有的值(类似列表的类型)

到此为止,本系列教程的python数据结构已经介绍完了,在本系列教程只是介绍了python中如何使用常用数据结构,并没有讲实现原理。而数据结构在计算机领域是不可或缺的,希望对数据结构了解甚少的读者可以认真学习一下数据结构的相关知识。

等学习完文件操作后,我们将用一个小项目实践一下(其实忽略文件操作,目前学到的知识还是可以做很多东西的),敬请期待! ( ̄︶ ̄)↗

python教程(七)·字典的更多相关文章

  1. 简明python教程七----面向对象的编程(下)

    继承:类之间的类型和子类型关系 代码重用:SchoolMember类被称为 基本类或超类,而Teacher和Student类被称为导出类或者子类 #!/usr/bin/python #Filename ...

  2. 简明python教程七----面向对象的编程

    根据操作数据的函数或语句块来设计程序的,被称为面向过程的编程. 把数据和功能结合起来,用称为对象的东西包裹起来的组织程序的方法,称为面向对象的编程理念. 类和对象是面向对象编程的两个主要方面.类创建一 ...

  3. 《简明python教程》笔记一

    读<简明Python教程>笔记: 本书的官方网站是www.byteofpython.info  安装就不说了,网上很多,这里就记录下我在安装时的问题,首先到python官网下载,选好安装路 ...

  4. python教程(零)·前言

    本教程是作者根据自己学习python的经验写下的,一来是想将经验分享给对python同样感兴趣的小白(大神请忽略),二来是想借此加深本人对python的理解,温故而知新. 学习基础 本教程面向的读者, ...

  5. (原+转)简明 Python 教程:总结

     简明 Python 教程 说明:本文只是对<简明Python教程>的一个总结.请搜索该书查看真正的教程. 第3章 最初的步骤 1. Python是大小写敏感的. 2. 在#符号右面的内容 ...

  6. 简学Python第七章__class面向对象高级用法与反射

    Python第七章__class面向对象高级用法与反射 欢迎加入Linux_Python学习群  群号:478616847 目录: Python中关于oop的常用术语 类的特殊方法 元类 反射 一.P ...

  7. 笔记|《简明Python教程》:编程小白的第一本python入门书

    <简明Python教程>这本书是初级的Python入门教材,初级内容基本覆盖,对高级内容没有做深入纠结.适合刚接触Python的新手,行文比较简洁轻松,读起来也比较顺畅. 下面是我根据各个 ...

  8. Python第七天 函数 函数参数 函数里的变量 函数返回值 多类型传值 函数递归调用 匿名函数 内置函数

    Python第七天   函数  函数参数   函数里的变量   函数返回值  多类型传值     函数递归调用   匿名函数   内置函数 目录 Pycharm使用技巧(转载) Python第一天   ...

  9. 学习笔记《简明python教程》

    学习笔记<简明python教程> 体会:言简意赅,很适合新手入门 2018年3月14日21:45:59 1.global 语句 在不使用 global 语句的情况下,不可能为一个定义于函数 ...

随机推荐

  1. 卸载Sharepoint2016后。重新安装提示 系统从以前的安装重新启动,或更新正在等待错误

    卸载Sharepoint2016 重启N遍,不停地重启.需要删除注册表项 下的 .将PendingFileRenameOperations键项删除,再重新安装就可以安装成功.

  2. HTTP协议图--HTTP 响应状态码(重点分析)

    1. 状态码概述 HTTP 状态码负责表示客户端 HTTP 请求的返回结果.标记服务器端的处理是否正常.通知出现的错误等工作. HTTP 状态码如 200 OK ,以 3 位数字和原因短语组成.数字中 ...

  3. java继承-重写-super实例补充

    方法重写: 是指子类根据需要父类继承来的方法进行改写,是多态机制的前奏. 重写注意点: 1.重写方法必须和被重写方法具有相同的方法名,参数列表和返回值. 2.重写方法方法不能使用比被重写方法更严格的访 ...

  4. Java虚拟机8:垃圾收集(GC)-3(垃圾收集算法)

    1.垃圾对象的判断 Java堆中存放着几乎所有的对象实例,垃圾收集器对堆中的对象进行回收前,要先确定这些对象是否还有用,判定对象是否为垃圾对象有如下算法: (1):引用计数算法 给对象添加一个引用计数 ...

  5. c++ 基类,派生类的类型兼容性

    #include <iostream> using namespace std; class CFather { public: void display() const { cout&l ...

  6. 基于session和cookie的登录验证(CBV模式)

    基于session和cookie的登录验证(CBV模式) urls.py """cookie_session URL Configuration The `urlpatt ...

  7. 31、springboot与任务

    异步任务 测试如下: 进行等待三秒在进行应答 @Service public class AsynService { public void hello(){ try { Thread.sleep() ...

  8. jquery 中 attr 和 prop 的区别

    问题:在jQuery引入prop方法后,什么时候使用attr,什么时候使用prop,两者区别. 判断: 对于HTML元素本身所有的固有属性,在处理的时候,使用prop方法 对于HTML元素后来我们自己 ...

  9. CUDA 纹理的使用

    纹理绑定有两种,一个是绑定到线性内存就是用cudaMalloc();cudaMemcpy();开辟的内存空间,另一种是绑定到cudaMallocArray, cudaMemcpyToArray开辟到的 ...

  10. disconf实践(一)Ubuntu16.04部署disconf

    在企业中,随着公司业务的扩张,用户量的增大,单一节点应用无法支撑正常的业务逻辑,比较常见的现象是访问速度变慢,甚至超时,严重时可能会造成系统宕机.为了尽量减少宕机的风险,单一节点系统需要进行水平扩展, ...