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


在现实生活中,查英语字典的时候,我们通常根据单词来查找意思。而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] += 1、x['abc'] = 2、x['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. CSS标准文档流 块级元素和行内元素

    标准文档流 什么是标准文档流 宏观的将,我们的web页面和ps等设计软件有本质的区别,web 网页的制作,是个“流”,从上而下 ,像 “织毛衣”.而设计软件 ,想往哪里画东西,就去哪里画 空白折叠现象 ...

  2. 初始python(一)

    一.python特性概要 1. python是解释性脚本语言. 2. python特性总结 2.1 字节码 2.2 动态语义 在赋值是确定数据类型 2.3 缩进(4个空格) 3. python定义编码 ...

  3. loadrunner测试c/s架构的应用系统

    用LoadRunner测试c/s架构的软件,怎样去选择协议,困扰了我很久,看到这篇文章,感觉有点收获,所以特意转了过来,希望对大家有用. 首先,什么是协议?协议无非就是一个约定,关于数据包发送的格式的 ...

  4. December 30th 2016 Week 53rd Friday

    Life without love is like a tree without blossoms or fruit. 缺少爱的生活就像从未开花结果的枯树. Love is not only the ...

  5. [COGS 2065]学数数

    2065. 学数数 ★★★☆   输入文件:jxthree.in   输出文件:jxthree.out   简单对比时间限制:1 s   内存限制:256 MB [题目描述] 从前有一只咩,还有一只叽 ...

  6. iOS自动化-iOS录屏xrecord及解决iPhone设备不显示的问题

    github地址:https://github.com/WPO-Foundation/xrecord 安装方法: git clone https://github.com/WPO-Foundation ...

  7. Vim常用命令记录

    (本文仅记录了Vim常用的按键功能和操作,用于备忘和查阅.若为Vim小白,建议先通过列出的参考资源获得对Vim更全面的了解.Vi 是几乎所有Linux发行版都支持的文字编辑工具,也是许多Linux下工 ...

  8. 友盟消息推送api、python sdk问题、测试demo代码

    一,友盟消息推送python服务端sdk地址和文档地址 1.sdk地址:http://dev.umeng.com/system/resources/W1siZiIsIjIwMTYvMDgvMTkvMT ...

  9. BZOJ1468:Tree(点分治)

    Description 给你一棵TREE,以及这棵树上边的距离.问有多少对点它们两者间的距离小于等于K Input N(n<=40000) 接下来n-1行边描述管道,按照题目中写的输入 接下来是 ...

  10. 解决 php7下 igbinary_unserialize_ref: invalid reference 的bug

    最近组内升级了PHP7,某个接口偶发502,看了下php的错误日志如下: igbinary_unserialize_ref: invalid reference >= Memcached::ge ...