零基础学Python--------第4章 序列的应用

时间:2021-09-26 22:51:49

第4章 序列的应用

4.1序列

序列是一块用于存放多个值的连续内存空间,并且按上一定顺序排列,每一个值(称为元素)都分配一个数字,称为索引或位置。通过该索引可以取出相应的值。例如,我们可以把一家酒店看作一个序列,那么酒店里的每个房间都可以看作是这个序列的元素。而房间号就相当于索引,可以通过房间号找到对应的房间。

在Python中,序列结构主要有列表、元组、集合、字典和字符串,对于这些序列结构有以下几个通用的操作。其中,集合和字典不支持索引、切片、相加和相乘操作。

4.1.1索引

序列中的每一个元素都一个编号,也称为索引。这个索引是从9开始递增的,即下标为0 表示第一个元素,下标为1 表示第2 个元素,以此类推。

……

Python比较神奇,它的索引可以是负数。这个索引从右向左计数,也就是从最后的一个元素开始计数,即最后一个元素的索引值是-1,倒数第二个元素的索引值为-2,以此类推。

……

注意:采用负数作为索引值时,是从-1开始的,而不是从0开始的,即最后一个元素的下标为-1,这是为了防止与第一个元素重合。

通过索引可以访问序列中的任何元素。例如,定义一个包括4 个元素的列表,要访问它的第 3个元素和最后一个元素,可以使用下面的代码:

verse = ["春眠不觉晓","Python不得了","夜来爬数据","好评知多少"]
print(verse[2]) # 输出第3个元素
print(verse[-1]) # 输出最后一个元素。

结果如下:

夜来爬数据
好评知多少
>>>

4.1.2切片

切片操作是访问序列中元素的另一种方法,它可以访问一定范围内的元素。通过切片操作可以生成一个新的序列。实现切片操作的语法格式如下:

sname[start : end : step]

参数说明:

  • sname:表示序列的名称。
  • start:表示切片开始位置(包括该位置),如果不指定,则默认为0。
  • end:表示切片的截止位置(不包括该位置),如果不指定,则默认为序列的长度。
  • step:表示切片的步长,如果省略,则默认为1,当省略该步长时,最后一个冒号也可以省略。

说明:在进行切片操作时,如果指定了步长,那么将按照该步长遍历序列的元素,否则将一个一个遍历序列。

例如,通过切片获取中国十大诗人(也称“中国近现代十大诗人”,在中国诗史上说法不一,较为公认指:胡适艾青徐志摩海子洛夫汪国真易白北岛舒婷席慕蓉食指。)列表中的第2 个到第5个元素,再获取第1 个、第3 个和第5 个元素,可以使用下面的代码:

poet = ["胡适","艾青","徐志摩","海子","洛夫","汪国真","易白","北岛","舒婷","席慕蓉","食指"]
print(poet[1:5]) # 获取第2个到第5个元素
print(poet[0:5:2]) # 获取第1个、第3个和第5个元素

运行代码如下:

['艾青', '徐志摩', '海子', '洛夫']
['胡适', '徐志摩', '洛夫']
>>>

说明:如果想要复制整个序列,可以将start 和end 参数都省略,但是中间的冒号需要保留。例如,poet[:]就表示复制整个名称为poet 的序列。

4.1.3序列相加

在Python中,支持两种同类型的序列相加操作,即将两个序列进行连接,不会去除重复的元素,使用(+) 运算符实现。例如,将两个列表相加,可以使用下面的代码;

poet1 = ["胡适","艾青","徐志摩","海子"]
poet2 = ["洛夫","汪国真","易白","北岛","舒婷","席慕蓉","食指"]
print(poet1+poet2)

说明:在进行 序列相加时,想同类型的序列是指同为列表、元组、集合等,序列中的元素类型可以不同。例如,下面的代码也是正确的;

num = [7,12,25,34,45,59,62,78]
poet = ["胡适","艾青","徐志摩","海子"]
print(num + poet)

但是不能将列表和元组相加,也不能将列表和字符串相加。例如,下面的代码就是错误的:

num = [7,12,25,34,45,59,62,78]
print(num + "胡适")

4.1.4乘法

在Python中,使用数字n 乘以一个序列会生成新的序列。新序列的内容为原来序列被重复n 次的结果。例如,下面的代码,将实现把一个序列乘以3 生成一个新的序列并输出,从而达到“重要事情说三遍”的效果。

love = ["我爱你","老婆!"]
print(love * 3)

在进行序列的乘法运算时,还可以实现初始化指定长度列表的功能。例如下面的代码,将创建一个长度为5 的列表,列表的每个元素都是None,表示什么都没有。

emptylist = [None]*5
print(emptylist)

运行上面的代码,将显示以下内容:

[None, None, None, None, None]

4.1.5检查某个元素是否是序列的成员

在Python中,可以使用in 关键字检查某个元素是否为序列的成员,即检查某个元素是否包含在某个序列中。语法格式如下:

value in sequence

其中,value表示要检查的元素,sequence表示指定的序列。

例如,要检查名称为poet 的序列中,是否包含元素“胡适”,可以使用下面的代码:

poet = ["胡适","艾青","徐志摩","海子"]
print("胡适" in poet)

运行上面的代码,将显示结果Ture,表示在序列中存在指定的元素。

另外,在Python中,也可以使用not in 关键字实现检查某个元素是否不包含在指定的序列中。例如下面的代码,将显示结果False。

poet = ["胡适","艾青","徐志摩","海子"]
print("胡适" not in poet)

4.1.6计算序列的长度、最大值和最小值

在Python中,提供了内置函数计算序列的长度、最大值和最小值。分别是:使用len() 函数计算序列的长度,即返回序列包含多少个元素;使用max() 函数返回序列中的最大元素;使用min() 函数返回序列中的最小元素。

例如,定义一个包括9个元素的列表,并通过len() 函数计算列表的长度,可以使用下面的代码:

num = [7,12,25,34,45,59,62,78,88]
print("序列num的长度为",len(num))

运行上面的代码,将显示以下结果:

序列num的长度为 9

……

除了上面介绍的3 个内置函数,Python还提供了下表的内置函数。

Python提供的内置函数及其作用
函数 作用
list() 将序列转换为列表
str() 将序列转换为字符串
sum() 计算元素和
sorted() 对元素进行排序
reversed() 反向序列中的元素
enumerate() 将序列组合为一个索引序列,多用在for 循环中

4.2列表

Python中的列表和歌曲列表类似,也是由一系列特定顺序排列的元素组成的。它是Python中内置的可变序列。在形式上,列表的所有元素都放在一对中括号“[]”中,两个相邻元素间使用逗号“,”分隔。在内容上,可以将整数、实数、字符串、列表、元组等任何类型的内容放入到列表中,并且同一个列表中,元素的类型可以不同,因为它们之间没有任何关系。由此可见,Python中的列表是非常灵活的,这一点与其他语言不同的。

4.2.1列表的创建和删除

1.使用赋值运算符直接创建列表

同其其他类型的Python变量一样,创建列表时,也可以使用赋值运算符“=”直接将一个列表赋值给变量,语法格式如下:

listname = [element 1,element 2,element 3,...,element n]

其中,listname表示列表的名称,可以是任何符合Python命名规则的标识符;“element 1,element 2,element 3,...,element n”表示列表中的元素,个数没有限制,并且只要是Python支持的数据类型就可以。

例如,下面定义的列表都是合法的:

num = [7,12,25,34,45,59,62,78,88]
verse = ['春江潮水连海平','海上明月共潮生','滟滟随波千万里','何处春江无月明']
untitle = ['Python',34,"人生苦短,我用Python",["爬虫","自动化运维","大数据","Web开发"]]
Python = ['优雅',"明确",'''简单''']

说明:在使用列表时,虽然可以将不同类型数据放入到同一个列表中,但是通常情况下,我们不这样做,而是在一个列表中只放入一种类型的数据。这样可以提高程序的可读性。

2.创建空列表

在Python中国,也可以创建空列表,例如,要创建一个名称为emptylist的空列表,可以使用下面的代码:

emptylist = []

3.创建数值列表

在Python中,数值列表很常用。例如,在考试系统中记录学生的成绩,或者在游戏中记录每个角色的位置、各个玩家的得分情况等都可以应用数值列表。在Python中,可以使用list() 函数直接将range() 函数循环出来的结果转换为列表。

list(data)

list() 函数的基本语法如下:

其中,data 表示可以转换列表的数据,其类型可以是range 对象、字符串、元组或者其他可迭代类型的数据。

例如,创建一个10~20之间(不包括20)所有偶数的列表,可以使用下面的代码:

>>> list(range(10,20,2))                    # 在Python shell里按Enter

运行上面的代码后,将得到下面的列表:

[10, 12, 14, 16, 18]

说明:使用list()函数不仅能通过range对象创建列表,还可以通过其他对象创建列表。

4.删除列表

对于已经创建的列表,不再使用时,可以使用del 语句将其删除。语法格式如下:

del listname

其中,listname为要删除列表的名称。

说明:del 语句在实际开发时,并不常用。因为Python自带的垃圾回收机制会自动销毁不用的列表,所以即使我们不手动将其删除,Python也会自动将其回收。

4.2.2访问列表元素

在Python中,如果想将列表的内容输出也比较简单,可以直接使用print()函数即可。例如,创建一个名称为untitle的列表,并打印列表,可以使用下面的代码:

untitle = ['Python',34,"人生苦短,我用Python",["爬虫","自动化运维","大数据","Web开发"]]
print(untitle)

执行结果如下:

['Python', 34, '人生苦短,我用Python', ['爬虫', '自动化运维', '大数据', 'Web开发']]

从上面的执行结果中可以看出,在输出列表时,是包括左右两侧的中括号的。如果不想要输出全部的元素,也可以通过列表的索引获取指定的元素。例如,要获取untitle列表中的索引2的元素,可以使用下面的代码:

print(untitle[2])
人生苦短,我用Python

从上面的执行结果中可以看出,在输出单个列表元素时,不包括中括号,如果是字符串,还不包括左右的引号。

实例01:输出每日一贴

import datetime                                 # 导入日期时间类
# 定义一个列表
mot = ["今天星期一:\n人生充满了不确定,和惊喜。",
"今天星期二:\n人生亦可燃烧,亦可腐败,我愿燃烧,耗尽所有的光芒。",
"今天星期三:\n毅力和耐性在某种程度上将决定一个人会成为什么样的人。",
"今天星期四:\n微笑拥抱每一天,做像向日葵般温暖的女子。",
"今天星期五:\n志在峰巅的攀登者,不会陶醉在沿途的某个脚印之中。",
"今天星期六:\n别小看任何人,越不起眼的人。往往会做些让人想不到的事。",
"今天星期日:\n我们可以失望,但不能盲目。"]
day = datetime.datetime.now().weekday() # 获取当期星期
print(mot[day]) # 输出每日一贴

说明:在上面的代码中,datetime.datetime.now()方法用于获取当期日期,而weekday()方法则是从日期时间对象中获取星期,其值为0~6中的一个,为0时代表星期一,为1时代表星期二,以此类推,为6时代表星期日。

上面介绍的是访问列表中的单个元素。实际上,列表还可以通过切片操作实现处理列表中的部分元素。

4.2.3遍历列表

遍历列表中的所有元素是常用的一种操作,在遍历的过程中可以完成查询、处理等功能。

1. 直接使用for 循环实现

直接使用for 循环遍历列表,只能输出元素的值,语法格式如下:

for item in listname:
# 输出item

其中,item 用于保存获取到的元素值,要输出元素内容是,直接输出该变量即可;listname 为列表名称。

例如,定义一个保存中国职业足球*联赛夺冠次数排行榜的列表,然后通过for 循环遍历该列表,并输出各个球队的名称,代码如下:

print("中国职业足球*联赛夺冠次数排行榜:")
team = ["大连实德","广州恒大淘宝","山东鲁能泰山","上海申花","深圳队","长春亚泰","北京中赫国安"]
for item in team:
print(item)

执行上面的代码结果如下:

中国职业足球*联赛夺冠次数排行榜:
大连实德
广州恒大淘宝
山东鲁能泰山
上海申花
深圳队
长春亚泰
北京中赫国安

2. 使用for 循环和enumerate() 函数实现

使用for 循环和enumerate() 函数可以实现同时输出索引值和元素内容,语法格式如下:

for index,item in enumerate(listname):
# 输出index 和item

参数说明:

  • index:用于保存元素的索引。
  • item:用于保存获取到的元素值,要输出元素内容时,直接输出该变量即可。
  • listname:为列表名称。

例如,定义一个保存中国职业足球*联赛夺冠次数排行榜的列表,然后通过for 循环和enumerate() 函数遍历该列表,并输出索引和球队名称,代码如下:

print("中国职业足球*联赛夺冠次数排行榜:")
team = ["大连实德","广州恒大淘宝","山东鲁能泰山","上海申花","深圳队","长春亚泰","北京中赫国安"]
for index,item in enumerate(team):
print(index + 1,item)

执行上面的代码,将显示下面的结果:

中国职业足球*联赛夺冠夺冠次数排行榜:
1 大连实德
2 广州恒大淘宝
3 山东鲁能泰山
4 上海申花
5 深圳队
6 长春亚泰
7 北京中赫国安

实例02:分两列显示中国职业足球*联赛夺冠夺冠次数排行榜的球队

在IDLE中创建一个名称为printteam.py的文件,并且在该文件中先输出标题,然后定义一个列表(保存球队名称),在应用for 循环和enumerate() 函数遍历列表,在循环体中通过if...else 语句判断是否为偶数,如果是偶数则不换行输出,否则换行输出。代码如下:

print("中国职业足球*联赛夺冠次数排行榜\n")
team = ["大连实德","广州恒大淘宝","山东鲁能泰山","上海申花","深圳队","长春亚泰","北京中赫国安"]
for index,item in enumerate(team):
if index%2 == 0: # 判断是否为偶数,为偶数时不换行
print(item + "\t\t",end='')
else:
print(item + "\n") # 换行输出

说明:在上面的代码中,在第5行的print() 函数中使用“end=''”表示不换行输出,即下一条print() 函数的输出内容会和这一内容在同一行输出。

运行结果如下:

中国职业足球*联赛夺冠次数排行榜

大连实德        广州恒大淘宝

山东鲁能泰山        上海申花

深圳队        长春亚泰

北京中赫国安

添加、修改和删除列表元素也称为更新列表。在实际开发时,经常需要对列表进行更新。下面我们介绍一下如何实现列表的添加、修改和删除。

1. 添加元素

在4.1 节介绍了可以通过“+” 号将两个序列连接,通过该方法也可以实现为列表添加元素。但是这种方法的执行速度要比直接使用列表对象的append() 方法慢,所以建议在实现添加元素时,使用列表对象的append() 方法实现。 列表对象的append() 方法用于在列表的末尾追加元素,语法格式如下:

listname.append(obj)

其中,listname为要添加元素的列表名称,obj 为要添加到列表末尾的对象。

例如,定义一个包括4 个元素的列表,然后应用append() 方法向该列表的末尾添加一个元素,可以使用下面的代码:

phone = ["小米","诺基亚","三星","夏新"]
len(phone) # 获取列表的长度
phone.append("传音")
len(phone) # 获取列表的长度
print(phone)

多学两招:列表对象除了提供append() 方法可以向列表中添加元素,还提供了insert() 方法也可以向列表中添加元素。该方法用于向列表的指定位置插入元素。但是由于该方法的执行效率没有append() 方法高,所以不推荐这种方法。

上面介绍的是向列表里添加一个元素,如果想要将一个列表中的全部元素添加到另一个列表中,可以使用列表对象的extend() 方法实现。extend() 方法的语法如下:

listname.extend(seq)

其中,listname 为原列表,seq 为要添加的列表。语句执行后,seq 的内容将追加到listname 的后面。

实例03:向NBA名人堂列表中追加2016年新进人的球星

创建一个保存2016年新进入球星名字的列表,再调用列表对象的extend() 方法追加元素,最后输出追加元素后的列表,代码如下:

# NBA名人堂原有人员
oldlist = ["迪肯贝·穆托姆博","迪克·巴维塔","约翰·卡利帕里","乔乔·怀特","斯宾塞·海伍德","丽萨·莱斯利","路易斯·丹皮尔","约翰·艾萨克斯","林德赛·盖茨","汤姆·海恩索恩","乔治·雷弗林"]
newlist = ["姚明" ,"阿伦·艾弗森","沙奎尔·奥尼尔"] # 新增人员列表
oldlist.extend(newlist) # 追加新球星
print(oldlist) # 显示新的NBA名人堂人员列表

2. 修改元素

修改列表中的元素只需要通过索引获取该元素,然后再为其重新赋值即可。例如,定义一个保存3 个元素的列表,然后修改索引值为2 的元素,代码如下:

verse = ["平生不会相思","才会相思","便害相思"]
print(verse)
verse[2] = "空一缕余香在此" # 修改列表的第3个元素
print(verse)

执行结果如下:

['平生不会相思', '才会相思', '便害相思']
['平生不会相思', '才会相思', '空一缕余香在此']

3. 删除元素

删除元素主要有两种情况,一种是根据索引删除,另一种是根据元素值进行删除。

  • 根据索引删除

删除列表中的指定元素和删除列表类似,也可以使用del 语句实现。所不同的就是在指定列表名称时,换为列表元素。例如,定义一个保存3 个元素的列表,删除最后一个元素,可以使用下面的代码:

verse = ["平生不会相思","才会相思","便害相思"]
del verse[-1]
print(verse)

执行结果如下:

['平生不会相思', '才会相思']
  • 根据元素值删除

如果想要删除一个不确定其位置的元素(即根据元素值删除),可以使用列表对象的remove() 方法实现。例如,要删除列表中内容为“武汉卓尔”的元素,可以使用下面的代码:

team = ["河南建业","杭州绿城","广州恒大","北京国安","山东鲁能","辽宁宏远","长春亚泰","江苏舜天","贵州人和","上海上港","天津泰达"]
team.remove("武汉卓尔")

使用列表对象的remove() 方法删除元素时,如果指定的元素不存在,将出现下面异常信息:

Traceback (most recent call last):
File "D:\python3.6.5\练习文件\demo.py", line 116, in <module>
team.remove("武汉卓尔")
ValueError: list.remove(x): x not in list
>>>

所以在使用remove()方法删除元素前,最好先判断该元素是否存在,改进后的代码如下:

team = ["河南建业","杭州绿城","广州恒大","北京国安","山东鲁能","辽宁宏远","长春亚泰","江苏舜天","贵州人和","上海上港","天津泰达"]
value = ("武汉卓尔") # 指定要移除的元素
if team.count(value)>0: # 判断要删除的元素是否存
team.remove(value) # 移除指定的元素
print(team)

说明:列表对象的count() 方法用于判断指定元素出现的次数,返回结果为0 时,表示不存在该元素。关于count() 方法的详细介绍请参见4.2.5 小节。

执行上面的代码后,将显示下面的列表原有内容:

['河南建业', '杭州绿城', '广州恒大', '北京国安', '山东鲁能', '辽宁宏远', '长春亚泰', '江苏舜天', '贵州人和', '上海上港', '天津泰达']

4.2.5 对列表进行统计和计算

Python 的列表提供了内置的一些函数来实现统计、计算的功能。下面介绍几种常用的功能。

1. 获取指定元素出现的次数

使用列表对象的count() 方法可以获取指定元素在列表中出现次数。基本语法格式如下:

listname.count(obj)

参数说明:

  • listname:表示列表的名称。
  • obj:表示要判断是否存在的对象,这里只能进行精确匹配,即不能是元素值的一部分。
  • 返回值:元素在列表中出现的次数。

例如,创建一个列表,内容为听众点播的歌曲列表,然后应用列表对象的count() 方法判断元素“遇见”出现的次数,代码如下:

song = ["遇见","十年","下沙","知心爱人","半沙壶","遇见","都是月亮惹的祸","天路"]
num = song.count("遇见")
print(num)

上面的代码运行后,结果将显示为2,表示“遇见”在song 列表中出现了两次。

2.获取指定元素首次出现的下标

使用列表对象的index() 方法可以获取指定元素在列表中首次出现的位置(即索引)。基本语法格式如下:

listname.index(obj)

参数说明

  • listname:表示列表的名称。
  • obj:表示要查找的对象,这里只能进行精确匹配。如果指定的对象不存在时,则抛出异常。
  • 返回值:首次出现的索引值。

代码如下:

song = ["遇见","十年","下沙","知心爱人","半沙壶","遇见","都是月亮惹的祸","天路"]
position = song.index("知心爱人")
print(position)

上面的代码运行后,将显示3 ,表示“知心爱人”在列表song 中首次出现的索引位置是3 。

3.统计数值列表的元素和

在Python中,提供了sum() 函数用于统计数值列表中各元素的和。语法格式如下:

sum(iterable[,start])

参数说明:

  • iterable:表示要统计的列表。
  • start:表示统计结果是从哪个数开始(即将统计结果加上start 所指定的数),是可选参数,如果没有指定,默认值为0 。

例如,定义一个保存10 名学生语文成绩的列表,然后应用sum() 函数统计列表中元素的和,即统计总成绩,然后输出,代码如下:

grade = [95,98,97,99,100,88,95,82,91,97]        # 10名学生的语文成绩列表
total = sum(grade) # 计算总成绩
print("语文总成绩为:",total)

4.2.6 对列表进行排序

Python 中提供了两种常用的对列表进行排序的方法:使用列表对象的sort() 方法,使用内置sorted() 函数。

1.使用列表对象的sort() 方法

列表对象提供了sort() 方法用于对原列表中的元素进行排序。排序后原列表中的元素顺序将发生改变。列表对象的sort() 方法的语法格式如下:

listname.sort(key = None,reverse = False)

参数说明:

  • listname:表示要进行排序的列表。
  • key:表示指定从每个元素中提取一个用于比较的键(例如,设置“key=str.lower”表示在排序时不区分字母大小写)。
  • reverse:可选参数,如果将其值指定为True,则表示降序排列;如果为False,则表示升序排列,默认为升序排列。

例如,定义一个保存10 名学生语文成绩的列表,然后应用sort() 方法对其进行排序,代码如下:

grade = [95,98,97,99,100,88,95,82,91,97]        # 10名学生的语文成绩列表
print("原列表:",grade)
grade.sort() # 进行升序排列
print("升 序:",grade)
grade.sort(reverse = True) # 进行降序排列
print("降 序:",grade)

执行上面的代码,将显示以下内容:

原列表: [95, 98, 97, 99, 100, 88, 95, 82, 91, 97]
升 序: [82, 88, 91, 95, 95, 97, 97, 98, 99, 100]
降 序: [100, 99, 98, 97, 97, 95, 95, 91, 88, 82]

使用sort() 方法进行数值列表的排序比较简单,但是使用sort() 方法对字符串列表进行排序时,采用的规则是先对大写字母排序,然后在对小写字母排序。如果想要对字符串列表进行排序(不区分大小写时),需要指出其key参数。例如,定义一个保存英文字符串的列表,然后应用sort() 方法对其进行升序排列,可以使用下面的代码:

char = ['cat','Tom','Angela','pet']
char.sort() # 默认区分字母大小写
print("区分字母大小写:",char)
char.sort(key=str.lower) # 不区分字母大小写
print("不区分字母大小写:",char)
说明:采用sort() 方法对列表进行排序时,对中文支持不好,排序的结果与我们常用的拼音排序法或者笔画排序法都不一致。如果需要实现对中文内容的列表排序,还需要重新编写相应的方法进行处理,不能直接使用sort() 方法。 

2.使用内置的sorted() 函数实现

在Python中,提供了一个内置的sorted() 函数,用于对列表进行排序。使用该函数进行排序后,原列表的元素顺序不变。sorted() 函数的语法格式如下:

sorted(iterable, key=None, reverse=False)

参数说明:

  • iterable:表示要进行排序的列表名称。
  • key:表示指定从每个元素中提取一个用于比较的键(例如,设置“key=str.lover”表示在排序时不区分字母大小写)。
  • reverse:可选参数,如果将其值指定为True,则表示降序排序;如果为False,则表示升序排列,默认为升序排列。

例如,定义一个保存10名学生语文成绩的列表,然后应用sorted() 函数对其进行排序,代码如下:

grade = [95,98,97,99,100,88,95,82,91,97]        # 10名学生的语文成绩列表
grade_as = sorted(grade) # 进行升序排列
print("升 序:",grade_as)
grade_des = sorted(grade,reverse = True) # 进行降序排列
print("降 序:",grade_des)
print("原列表:",grade)

执行上面的代码,将显示以下内容:

升  序: [82, 88, 91, 95, 95, 97, 97, 98, 99, 100]
降 序: [100, 99, 98, 97, 97, 95, 95, 91, 88, 82]
原列表: [95, 98, 97, 99, 100, 88, 95, 82, 91, 97]

说明:列表对象的sort() 方法和内置sorted() 函数的作用基本相同;不同点是在使用sort() 方法时,将会改变原列表的元素排列顺序,而使用sorted() 函数时,会建立一个原列表的副本,该副本为排序后的列表。

4.2.7 列表推导式

使用列表推导式可以快速生成一个列表,或者根据某个列表生成满足指定需求的列表。列表推导式通常有以下几种常用的语法格式。

(1)生成指定范围的数值列表,语法格式如下:

list = [Expression for var in range]

参数说明:

  • list:表示生成的列表名称。
  • Expression:表达式,用于计算新列表的元素。
  • var:循环变量。
  • range:采用range()函数生成的range 对象。

例如,要生成一个包括10 个随机数的列表,要求数的范围在10~100(包括)之间,具体代码如下:

import random                   # 导入random标准库
randomnumber = [random.randint(10,100) for i in range(10)]
print("生成的随机数为:",randomnumber)

执行结果如下:

生成的随机数为: [25, 82, 96, 65, 18, 74, 78, 98, 100, 50]

(2)根据列表生成指定需求的列表,语法格式如下:

newlist = [Expression for var in list]

参数说明:

  • newlist:表示新生成的列表名称。
  • Expression:表达式,用于计算新列表的元素。
  • var:变量,值为后面列表的每个元素值。
  • list:用于生成新列表的原列表。

例如,定义一个记录商品价格的列表,然后应用列表推导式生成一个将全部商品价格打五折的列表,具体代码如下:

price = [3251,1000,2510,4585,8525,5666]
sale = [int(x*0.5) for x in price]
print("原价格:",price)
print("打五折的价格",sale)

执行结果如下:

原价格: [3251, 1000, 2510, 4585, 8525, 5666]
打五折的价格 [1625, 500, 1255, 2292, 4262, 2833]

(3)从列表中选择符合条件的元素组成新的列表,语法格式如下:

newlist = [Expression for var in list if condition]

参数说明:

  • newlist:表示新生成的列表名称。
  • Expression:表达式,用于计算新列表的元素。
  • var:变量,值为后面列表的每个元素值。
  • list:用于生成新列表的原列表。
  • condition:条件表达式,用于指定筛选条件。

例如,定义一个记录商品价格的列表,然后应用列表推导式生成一个商品价格高于5000元的列表,具体代码如下:

price = [3251,1000,2510,4585,8525,5666]
sale = [x for x in price if x>5000]
print("原价格:",price)
print("价格高于5000:",sale)

4.2.8 二维列表的使用

二维列表中的信息以行和列的形式表示,第一个下标代表元素所在的行,第二个下标代表元素所在的列。在Python中,创建二维列表有以下三种常用的方法。

1. 直接定义二维列表

在Python中,二维列表是包含列表的列表,即一个列表的每一个元素又都是一个列表。

……

2.使用嵌套的for 循环创建

创建二维列表,可以使用嵌套的for 循环实现。例如,创建一个包含4 行5 列的二维列表,可以使用下面的代码:

arr = []                    # 创建一个空列表
for i in range(4):
arr.append([]) # 在空列表中再添加一个空列表
for j in range(5):
arr[i].append(j) # 为内层列表添加元素
print(arr)

上面代码在执行后,将创建以下二维列表:

[[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]]

3. 使用列表推导式创建

使用推导式也可以创建二维列表,因为这种方法比较简洁,所以建议使用这种方法创建二维列表。例如,使用列表推导式创建一个包含4 行5 列的二维列表可以使用下面的代码:

arr = [[j for j in range(5)] for i in range(4)]
print(arr)

上面代码在执行后,将创建以下二维列表:

[[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]]

创建二维数组后,可以通过以下语法格式访问列表中的元素:

listname[下标1][下标2]

参数说明:

  • listname:列表名称。
  • 下标1:表示列表中第几行,下标值从0 开始,即第一行的小标为0 。
  • 下标2:表示列表中第几行,下标值从0 开始,即第一行的下标为0 。

例如,要访问二维列表中的第2 行,第4列,可以使用下面的代码:

verse[1][3]

实例04:使用二维列表输出不同版式的古诗

在IDLE 中 创建一个文件,然后在该文件中首先定义4 个字符串,内容为柳宗元的《江雪》中的诗句,并定义一个二维列表,然后应用嵌套的for 循环将古诗以横版方式输入,再将二维列表进行逆序排列,最后应用嵌套的for 循环将古诗以竖版方式输出,代码如下:

str1 = "千山鸟飞绝"
str2 = "万径人踪灭"
str3 = "孤舟蓑笠翁"
str4 = "独钓寒江雪"
verse = [list(str1),list(str2),list(str3),list(str4),] # 定义一个二维列表
print("\n-- 横板 --\n")
for i in range(4): # 循环古诗的每一行
for j in range(5): # 循环每一行的每一个字(列)
if j == 4: # 如果是一行中的最后一个字
print(verse[i][j]) # 换行输出
else:
print(verse[i][j],end="") # 不换行输出 verse.reverse() # 对列表进行逆序排列
print("\n-- 竖版 --\n")
for i in range(5): # 循环每一行的每个字(列)
for j in range(4): # 循环新逆序排列后的第一行
if j == 3: # 如果是最后一行
print(verse[j][i]) # 换行输出
else:
print(verse[j][i],end="") # 不换行输出

说明:在上面的代码中,list() 函数用于将字符串转换为列表;列表对象的reverse() 方法用于对列表进行逆序排列,即将列表的最后一个元素移到第一个,倒数第二个元素移到第二个,以此类推。

运行结果如下:

-- 横板 --

千山鸟飞绝
万径人踪灭
孤舟蓑笠翁
独钓寒江雪 -- 竖版 -- 独孤万千
钓舟径山
寒蓑人鸟
江笠踪飞
雪翁灭绝

4.3 元组

元组(tuple)是Python 中另一个重要的序列结构,与列表类似,也是由一系列按特定顺序排列的元素组成,但是它是不可变序列。因此,元组也可以成为不可变的列表。在形式上,元组的所有元素都放在一对“0” 中,两个相邻元素间使用“,” 分隔。在内容上,可以将整数、实数、字符串、列表、元组等任何类型的内容放入到元组中,并且在同一个元组中,元素的类型可以不同,因为它们之间没有任何关系。通常情况下,元组用于保存程序中不可修改的内容。

说明:从元组和列表的定义上看,这两种结构比较相似,二者之间的主要区别为:元组是不可变序列,列表是可变序列。即元组中的元素不可以单独修改,而列表则可以任意修改。

4.3.1 元组的创建和删除

在Python中提供了多种创建元组的方法,下面分别进行介绍。

1. 使用赋值运算符直接创建元组

同其他类型的Python 变量一样,创建元组时,也可以使用赋值运算符“=” 直接将一个元组赋值变量。语法格式如下:

tuplename = (element 1,element 2,element 3,...,element n)

其中,tuplename 表示元组的名称,可以是任何符合Python 命名跪着的标识符;elemnet 1、elemnet 2、elemnet 3、elemnet n表示元组中的元素,个数没有限制,并且只要为Python 支持的数据类型就可以。

注意:创建元组的语法与创建列表的语法类似,只是创建列表时使用的是“[]” ,而创建元组时使用的是“()”。

例如,下面定义的都是合法的元组:

num = (13,15,45,55,65,89,122)
ukguzheng = ("悯农","两小无猜","宫保鸡丁","特朗普")
untitle = ('Python',‘34’,("人生苦短","我用Python")["盘存","爬虫","云计算","区域链"])
python = ('聪明',"小明",'''孔明''')

在Python中,元组使用一对小括号将所有的元素括起来,但是小括号并不是必须的,只要将一组值用逗号分隔开来,Python 就可以视其为元组。例如,下面的代码定义的也是元组:

ukguzheng = "悯农","两小无猜","宫保鸡丁","特朗普"
print(ukguzheng)

在IDLE 中输出该元组后,将显示以下内容:

('悯农', '两小无猜', '宫保鸡丁', '特朗普')

如果要创建的元组只包括一个元素,则需要在定义元组时,在元素的后面加一个逗号“,” 。例如,下面的代码定义的就是包括一个元素的元组:

verse1 = ("无边光景一时新",)
print(verse1)

在IDLE 中输入verse1,将显示以下内容:

('无边光景一时新',)

而下面的代码,则表示定义一个字符串:

verse2 = ("无边光景一时新")
print(verse2)

在IDLE 中输出verse2,将显示以下内容:

无边光景一时新

说明:在Python 中,可以使用type() 函数测试变量的类型,如下面的代码:

verse1 = ("无边光景一时新",)
print("verse1的类型为",type(verse1))
verse2 = ("无边光景一时新")
print("verse2的类型为",type(verse2))

在IDLE 中执行上面的代码,将显示以下内容:

verse1的类型为 <class 'tuple'>
verse2的类型为 <class 'str'>

2. 创建空元组

在Python 中,也可以创建空元组,例如,创建一个名称为emptytuple 的空元组,可以使用下面的代码:

emptytuple = ()

空元组可以应用在为函数传递一个空值或者返回空值时。例如,定义一个函数必须传递一个元组类型的值,而我们还不想为它传递一组数据,那么就可以创建一个空元组传递给它。

3. 创建数值元组

在Python 中,可以使用tuple() 函数直接将range() 函数循环出来的结果转换为数值元组。

tuple() 函数的基本语法如下:

tuple(data)

其中,data 表示可以转换为元组数据,其类型可以是range 对象、字符串、元组或者其他可迭代类型的数据。

例如,创建一个10~20(不包括20)所有偶数的元组,可以使用下面的代码:

tuple(range(10,20,2))

运行上面的代码后,将得到下面的列表:

(10, 12, 14, 16, 18)

说明:使用tuple() 函数不仅能通过range 对象创建元组,还可以通过其他对象创建元组。

4. 删除元组

对于已经创建的元组,不再使用时,可以使用del 语句将其删除。语法格式如下:

del tuplename

其中,tuplename 为要删除元组的名称。

说明:del 语句在实际开发时,并不常用。因为跑一趟红 自带的垃圾回收机制会自动销毁不用的元组,所以即使我们不手动将其删除,Python 也会自动将其回收。

例如,定义一个名称为verse 的元组,然后再应用del 语句将其删除,可以使用下面的代码:

verse = ("洞房昨夜春风起","故人尚隔湘江水","枕上片时春梦中","行尽江南数千里")
del verse

实例05:使用元组保存咖啡馆里提供的咖啡名称

……代码如下:

coffeename = ("蓝山","卡布奇诺","曼特宁","摩卡","哥伦比亚")            # 定义元组
print(coffeename)

运行结果如下:

('蓝山', '卡布奇诺', '曼特宁', '摩卡', '哥伦比亚')

4.3.2 访问元组元素

在Python 中,如果想将元组的内容输出也必将简单,可以直接使用print() 函数即可。例如,要想打印上面元组中的untitle 元组,可以使用下面的代码:

untitle = ('Python',34,("人生苦短,我用Python"),["爬虫","自动化运维","大数据","Web开发"])
print(untitle)

  执行结果如下:

('Python', 34, '人生苦短,我用Python', ['爬虫', '自动化运维', '大数据', 'Web开发'])

从上面的执行结果中可以看出,在输出元组时,是包括左右两侧的小括号的。如果不想要输出全部的元素,也可以通过元组的索引获取指定的元素。例如,要获取元组untitle 中索引为0 的元素,可以使用下面的代码:

untitle =

('Python',34,("人生苦短,我用Python"),["爬虫","自动化运维","大数据","Web开发"])

print(untitle[0])

执行结果如下:

Python

从上面的执行结果中可以看出,在输出单个元组元素时,不包括小括号,如果是字符串,还不包括左右的引号。

另外,对于元组也可以采用切片方式获取指定的元素。例如,要访问元组untitle 中前3个元素,可以使用下面的代码:

untitle = ('Python',34,("人生苦短,我用Python"),["爬虫","自动化运维","大数据","Web开发"])
print(untitle[:3])

执行结果如下:

('Python', 34, '人生苦短,我用Python')

同列表一样,元组也可以使用for 循环进行遍历。下面通过一个具体的实例演示如何通过for 循环遍历元组。

场景模拟:客人到了,服务员向客人介绍本店提供的咖啡。

实例06:使用for 循环列出咖啡馆里的咖啡名称

应用for 循环语句输出每个元组元素的值,即咖啡名称,并且在后面加上“咖啡”二字,代码如下:

coffeename = ("蓝山","卡布奇诺","曼特宁","摩卡","哥伦比亚","麝香猫")            # 定义元组
print("你好,欢迎光临 ~ 伊米咖啡馆 ~ \n\n我店有:\n")
for name in coffeename: # 遍历元组
print(name + "咖啡",end = "")

运行结果如下:

你好,欢迎光临 ~ 伊米咖啡馆  ~ 

我店有:

蓝山咖啡卡布奇诺咖啡曼特宁咖啡摩卡咖啡哥伦比亚咖啡麝香猫咖啡

另外,元组还可以使用for 循环和enumerate() 函数结合进行遍历。下面通过一个具体的实例演示如何在for 循环中通过enumerate() 函数遍历元组。

说明:enumerate() 函数用于将一个可遍历的数据对象(如列表或元组)组合为一个索引序列,同时列出数据和数据下标,一般在for 循环中使用。

实例07:分两列显示中国职业足球*联赛夺冠次数排行榜(实例02相同)

print("中国职业足球*联赛夺冠次数排行榜\n")
team = ["大连实德","广州恒大淘宝","山东鲁能泰山","上海申花","深圳队","长春亚泰","北京中赫国安"]
for index,item in enumerate(team):
if index%2 == 0: # 判断是否为偶数,为偶数时不换行
print(item + "\t\t",end='')
else:
print(item + "\n") # 换行输出

4.3.3 修改元组元素

场景模拟:伊米咖啡馆,由于哥伦比亚咖啡需求量较大,库存不足,店长向把它换成拿铁咖啡。

实例08:将哥伦比亚咖啡代替为拿铁咖啡

修改其中第5 个元素的内容为“拿铁”,代码如下:

coffeename = ("蓝山","卡布奇诺","曼特宁","摩卡","哥伦比亚","麝香猫")            # 定义元组
coffeename[4] = "拿铁" # 将"哥伦比亚"代替为"拿铁"
print(coffeename)

运行结果如下:

Traceback (most recent call last):
File "D:\python3.6.5\练习文件\demo.py", line 331, in <module>
coffeename[4] = "拿铁" # 将"哥伦比亚"代替为"拿铁"
TypeError: 'tuple' object does not support item assignment

出现异常

元组是不可变序列,所以我们不能对它的单个元素值进行修改。但是元组也不是完全不能修改。我们可以对元组进行重新赋值。例如,下面的代码是允许的:

coffeename = ("蓝山","卡布奇诺","曼特宁","摩卡","哥伦比亚","麝香猫")            # 定义元组
coffeename = ("蓝山","卡布奇诺","曼特宁","摩卡","拿铁","麝香猫") # 对元组进行重新赋值
print("新元组",coffeename)

执行结果如下:

新元组 ('蓝山', '卡布奇诺', '曼特宁', '摩卡', '拿铁', '麝香猫')

另外,还可以对元组进行连接组合。例如,可以使用下面的代码实现在已经存在的元组结尾处添加一个新元组。

ukguzheng = ("蓝山","卡布奇诺","曼特宁","摩卡")
print("原元组:",ukguzheng)
ukguzheng = ukguzheng + ("哥伦比亚","麝香猫")
print("组合后:",ukguzheng)

执行结果后:

原元组: ('蓝山', '卡布奇诺', '曼特宁', '摩卡')
组合后: ('蓝山', '卡布奇诺', '曼特宁', '摩卡', '哥伦比亚', '麝香猫')

注意:在进行元组连接时,连接的内容必须都是元组。不能将元组和字符串或者列表进行连接。例如,下面的代码就是错误的。

ukguzheng = ("蓝山","卡布奇诺","曼特宁","摩卡")
print("原元组:",ukguzheng)
ukguzheng = ukguzheng + ["哥伦比亚","麝香猫"]
print("组合后:",ukguzheng)

常见错误:在进行元组连接时,如果要连接的元组只有一个元素时,一定不要忘记后面的逗号。例如,使用下面的代码将产生错误。

ukguzheng = ("蓝山","卡布奇诺","曼特宁","摩卡")
print("原元组:",ukguzheng)
ukguzheng = ukguzheng + ("哥伦比亚")
print("组合后:",ukguzheng)

4.3.4 元组推导式

使用元组推导式可以快速生成一个元组,它的表现形式和列表推导式类似,只是将列表推导式中的“[]” 修改为“()” 。例如,我们可以使用下面的代码生成一个包含10 个随机数的元组。

import random               # 导入random标准库
randomnumber = (random.randint(10,100) for i in range(10))
print("生成的元组为:",randomnumber)

执行结果如下:

生成的元组为: <generator object <genexpr> at 0x02DA1120>

从上面的执行结果中,可以看出使用元组推导式生成的结果并不是一个元组或者列表,而是一个生成器对象,这一点和列表推导式是不同的。要使用该生成器对象可以将其转换为元组或者列表。其中,转换为元组使用tuple() 函数,而转换为列表则使用list() 函数。

例如,使用元组推导式生成一个包含10 个随机数的生成器对象,然后将其转换为元组并输出,可以使用下面的代码:

import random                       # 导入random标准库
randomnumber = (random.randint(10,100) for i in range(10))
randomnumber = tuple(randomnumber) # 转换为元组
print("转换后:",randomnumber)

执行结果如下:

转换后: (81, 95, 91, 87, 53, 16, 77, 33, 59, 11)

要使用通过元组推导器生成的生成器对象,还可以直接通过for 循环遍历或者直接使用__next__() 方法进行遍历。

说明:在Python 2.x 中,__next__() 方法对应的方法为next() 方法,也是用于遍历生成器对象的。

例如,通过生成器推导式生成一个包括3 个元素的生成器对象number,然后调用3次__next__() 方法输出每个元素,再将生成器对象number 转换为元组输出,代码如下:

number = (i for i in range(3))
print(number.__next__()) # 输出第1个元素
print(number.__next__()) # 输出第1个元素
print(number.__next__()) # 输出第1个元素
number = tuple(number) # 转换为元组
print("转换后:",number)

上面的代码运行后,将显示以下的结果:

0
1
2
转换后: ()

再如,通过生成器推导式生成一个包括4个元素的生成器对象number,然后应用for 循环遍历该生成器对象,并输出每一个元素的值,最后再将其转换为元组输出,代码如下:

number = (i for i in range(4))          # 生成生成器对象
for i in number: # 遍历生成器对象
print(i,end='') # 输出每个元素的值
print(tuple(number)) # 转换为元组输出

执行结果如下:

0123()

从上面的两个示例中可以看出,无论通过哪种方法遍历,如果再想使用该生成器对象,都必须重新创建一个生成器对象,因为遍历后原生成器对象已经不存在了。

4.3.5 元组与列表的区别

元组和列表都属于序列,而且它们又都可以按照特定顺序存放一组元素,类型又不受限制,只要是Python支持的类型都可以。那么它们之间有什么区别呢?

列表类似于我们用铅笔在纸上写下自己喜欢的歌词,写错了还可以擦掉:而元组则类似于用钢笔写下的歌词,写错了就擦不掉了,除非换一张纸重写。

列表和元组的区别主要体现在以下几个方面:

  • 列表属于可变序列,它的元素可以随时以修改或者删除;:元组属于不可变序列,其中的元素不可以修改,除非整体替换。
  • 列表可以使用 append()、 extend()、 Insert()、 remove()和pop()等方法实现添加和修改列表元素,而元组没有这几个方法,所以不能向元组中添加和修改元素。同样,元组也不能删除元素。
  • 列表可以使用切片访问和修改列表中的元素。元组也支持切片,但是它只支持通过切片访问元组中的元素,不支持修改。
  • 元组比列表的访问和处理速度快,所以当只是需要对其中的元素进行访问,而不进行任何修改时,建议使用元组。
  • 列表不能作为字典的键,而元组则可以。

4.4 字典

在 Python中,字典与列表类似,也是可变序列,不过与列表不同,它是无序的可变序列,保存的内容是以“键-值对”的形式存放的。这类似于我们的新华字典,它可以把拼音和汉字关联起来,通过音节表可以快速找到想要的汉字。其中新华字典里的音节表相当于键(key),而对应的汉字,相当于值( value)。键是唯一的,而值可以有多个。字典在定义一个包含多个命名字段的对象时,很有用。

字典的主要特征如下:

  • 通过键而不是通过索引来读取

字典有时也称为关联数组或者散列表(hash)。它是通过键将一系列的值联系起来的,这样就可以通过键从字典中获取指定项,但不能通过索引来获取。

  • 字典是任意对象的无序集合

字典是无序的,各项是从左到右随机排序的,即保存在字典中的项没有特定的顺序。这样可以提高查找效率。

  • 字典是可变的,并且可以任意嵌套

字典可以在原处增长或者缩短(无须生成一个副本)。并且它支持任意深度的嵌套(即它的值可以是列表或者其他的字典)。

  • 字典中的键必须唯一

不允许同一个键出现两次,如果出现两次,则后一个值会被记住

  • 字典中的键必须不可变

字典中的键是不可变的,所以可以使用数字、字符串或者元组,但不能使用列表

说明: Python中的字典相当于Java或者C++中的Map对象

4.4.1字典的创建和删除

定义字典时,每个元素都包含两个部分“键”和“值”。

创建字典时,在“键”和“值”之间使用冒号分隔,相邻两个元素使用逗号分隔,所有元素放在一对“{}” 中。语法格式如下:

dictionary = {'key1':'value1','key2':'value2',...'keyn':'valuen',}

参数说明:

  • dictionary:表示字典名称。
  • key1、key2...valuen:表示元素的键,必须是唯一的,并且不可变,例如,可以是字符串、数字或者元组。
  • value1、value2...valuen:表示元素的值,可以是任何数据类型,不是必须唯一的。
  • 例如,创建一个保存通讯录信息的字典,可以使用下面的代码:
dictionary = {'qq':'','伊米咖啡馆':'','牧牛人':'024-999666'}
print(dictionary)

执行结果如下:

{'qq': '', '伊米咖啡馆': '', '牧牛人': '024-999666'}

同列表和元组一样,也可以创建空字典。在Python中,可以使用下面两种方法创建空字典:

dictionary = {}

或者

dictionary = dict()

Python 中的dict() 方法除了可以创建一个空字典外,还可以通过已有数据快速创建字典。主要表现为以下两种形式:

1. 通过映射函数创建字典

dictionary = dict(zip(list1,list2))

参数说明:

  • dictionary:表示字典名称。
  • zip() 函数:用于将多个列表或元组对应位置的元素组合为元组,并返回包含着些内容的zip 对象。如果想获取元组,可以将zip 对象使用tuple() 函数转换为元组;如果想获取列表,则可以使用list() 函数将其转换为列表。

实例09:创建一个保存女神星座的字典

在IDLE 中创建一个名称为sign_create.py的文件,然后在该文件中,定义两个包括4 个元素的列表,在应用dict() 函数和zip() 函数将前两个列表转换为对应的字典,并且输出该文字典,代码如下:

name = ['月蓝星晨寒','生怕帅哭你','溫酒燙眉山','细雨如愁']          # 作为键的列表
sign = ['天秤座','金牛座','处女座','双子座'] # 作为值的列表
dictionary = dict(zip(name,sign)) # 转换为字典
print(dictionary) # 输出转换后字典

运行实例后,结果如下:

月蓝星晨寒': '天秤座', '生怕帅哭你': '金牛座', '溫酒燙眉山': '处女座', '细雨如愁': '双子座'}

同列表和元组一样,不再需要的字典也可以使用del 命令删除整个字典。例如,通过下面的代码即可将已经定义的字典删除。

del dictionary

另外,如果只是想删除字典的全部元素,可以使用字典对象的clear() 方法实现。执行clear() 方法后,原字典将变为空字典。例如,下面的代码将清除字典的全部元素。

dictionary.clear()

4.4.2 通过键值对访问字典

在使用字典时,很少直接输出它的内容。一般需要根据指定的键得到相应的结果。在Python 中,访问字典的元素可以通过下标的方式实现,与列表和元组不同,这里的下标不是索引号,而是键。例如,想要访问“生拍帅哭你”的星座,可以使用下面的代码:

name = ['月蓝星晨寒','生怕帅哭你','溫酒燙眉山','细雨如愁']          # 作为键的列表
sign = ['天秤座','金牛座','处女座','双子座'] # 作为值的列表
dictionary = dict(zip(name,sign)) # 转换为字典
print(dictionary['生怕帅哭你']) # 输出转换后字典

执行结果如下:

金牛座

在实际开发中,我们不可能知道当前存在什么键,所以需要避免该异常的产生。具体的解决方法是使用if 语句对不存在的情况进行处理,即设置一个默认值。例如,可以将上面的代码修改为以下内容:

name = ['月蓝星晨寒','生怕帅哭你','溫酒燙眉山','细雨如愁']          # 作为键的列表
sign = ['天秤座','金牛座','处女座','双子座'] # 作为值的列表
dictionary = dict(zip(name,sign)) # 转换为字典
print("帅哭你的星座是:",dictionary['帅哭你'] if '帅哭你' in dictionary else '我的字典里没有此人')

当“帅哭你”不存在时,将显示以下内容:

帅哭你的星座是: 我的字典里没有此人

另外,Python 中推荐的方法是使用字典对象的get() 方法获取指定键的值,语法格式如下:

dictionary.get(key[,default])

参数说明:

  • dictionary:为字典对象,即要从中获取值的字典。
  • key:为指定的键。
  • default:为可选项,用于指定当指定的“键”不存在时,返回一个默认值,如果省略,则返回None。

例如,通过get() 方法获取“生怕帅哭你”的星座,可以使用下面的代码:

name = ['月蓝星晨寒','生怕帅哭你','溫酒燙眉山','细雨如愁'] # 作为键的列表
sign = ['天秤座','金牛座','处女座','双子座'] # 作为值的列表
dictionary = dict(zip(name,sign)) # 转换为字典
print("生怕帅哭你的星座是:",dictionary.get('生怕帅哭你'))

执行结果如下:

生怕帅哭你的星座是: 金牛座

说明:为了解决在获取指定键的值时,因为不在该键而导致抛出异常,可以为get() 方法设置默认值,这样当指定的键不存在时,得到结果就是指定的默认值。例如,将上面的代码修改为以下内容。

name = ['月蓝星晨寒','生怕帅哭你','溫酒燙眉山','细雨如愁']          # 作为键的列表
sign = ['天秤座','金牛座','处女座','双子座'] # 作为值的列表
dictionary = dict(zip(name,sign)) # 转换为字典
print("帅哭你的星座是:",dictionary.get('帅哭你','我的字典里没有此人'))

将得到以下结果:

帅哭你的星座是: 我的字典里没有此人

实例10:根据星座测试性格特点

……

4.4.3 遍历字典

字典是以“键-值对”的形式存储数据的,所以需要通过这些“键-值对”进行获取。Python提提供了遍历字典的方法,通过遍历可以获取字典中的全部“键-值对”。

使用字典对象的items() 方法可以获取字典的“键-值对”列表,语法格式如下:

dictionary.items()

其中,dictionary 为字典对象;返回值为可遍历的(键-值对)的元组列表。想要获取到具体的“键-值对”,可以通过for 循环遍历给元组列表。

例如,定义一个字典,然后通过items() 方法获取“键-值对”的元组列表,并输出全部“键-值对”,代码如下:

dictionary = {'qq':'','伊米咖啡馆':'','牧牛人':'024-999666'}
for item in dictionary.items():
print(item)

执行结果如下:

('qq', '')
('伊米咖啡馆', '')
('牧牛人', '024-999666')
>>>

上面的例子获取的是字典中的各个元素,如果想要获取具体的每个键和值,可以使用下面的代码进行遍历。

dictionary = {'qq':'','伊米咖啡馆':'024-88885555','牧牛人':'024-99996666'}
for key,value in dictionary.items():
print(key,"的联系电话是",value)

执行结果如下:

qq 的联系电话是 12345
伊米咖啡馆 的联系电话是 024-88885555
牧牛人 的联系电话是 024-99996666

说明:在Python中,字典对象还提供了values()方法和keys()方法,用于返回字典的“值”和“键”列表,它们的使用方法同items()方法类似,也需要通过for 循环遍历该字典列表,获取对应的值和键。

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

由于字典是可变序列,所以可以随时在字典中添加“键-值对”。向字典中添加元素的语法格式如下:

dictionary[key] = value

参数说明:

  • dictionary:表示字典名称。
  • key:表示要添加元素的键,必须是唯一的,并且不可变,例如可以是字符串、数字或者元组。
  • value:表示元素的值,可以是任何数据类型,不是必须唯一的。

例如,还以保存4位网友星座的场景为例,在创建的字典中添加一个元素,并显示添加后的字典,代码如下:

dictionary = dict((('月蓝星晨寒','天秤座'),('生怕帅哭你','金牛座'),('溫酒燙眉山','处女座'),('细雨如愁','双子座')))
dictionary["上善若水"] = "巨蟹座" # 添加一个元素
print(dictionary)

执行结果如下:

{'月蓝星晨寒': '天秤座', '生怕帅哭你': '金牛座', '溫酒燙眉山': '处女座', '细雨如愁': '双子座', '上善若水': '巨蟹座'}

……

因此,为防止删除不存在的元素时抛出异常,可将上面的代码修改成如下内容:

dictionary = dict((('月蓝星晨寒','天秤座'),('生怕帅哭你','金牛座'),('溫酒燙眉山','处女座'),('细雨如愁','双子座')))
if"生怕帅哭你1" in dictionary: # 如果存在
del dictionary["生拍帅哭你1"] # 删除一个元素
print(dictionary)

4.4.5 字典推导式

使用字典推导式可以快速生成一个字典,它的表现形式和列表推导式类似。例如,我们可以使用下面的代码生成一个包含4 个随机数的字典,其中字典的键使用数字表示。

import random               # 导入random标准库
randomdict = {i:random.randint(10,100) for i in range(1,5)}
print("生成的元组为:",randomdict)

执行结果如下:

生成的元组为: {1: 91, 2: 75, 3: 16, 4: 39}

实例11:应用字典推导式实现根据名字和星座创建一个字典

……

4.5 集合

Python 中的集合同数学中的集合概念类似,也是用于保存不重复元素的。它有可变集合(set)和不可变集合(frozenset)两种。本节所介绍的可变集合是无序可变序列,而不可变集合在本书中不做介绍。在形式上,集合的所有元素都放在一对“{}”中,两个乡里元素间使用“,”分隔。集合最好的应用就是去掉重复元素,因为集合中的每个元素都是唯一的。

集合最常用的操作就是创建集合,以及集合的添加、删除、交集和差集等运算,下面分别进行介绍。

4.5.1 集合的创建

在Python 中提供了两种创建集合的方法:一种是直接使用“{}”创建,另一种是通过set() 函数将列表、元组等可迭代对象转换为集合。这里推荐使用第二种方法。

1. 直接使用“{}” 创建集合

在Python中,创建set 集合也可以向列表、元组和字典一样,直接将集合赋值给变量从而实现创建集合,即直接使用“{}” 创建。语法格式如下:

setname = {element 1,element 2,element 3,...,element n,}

参数说明:

  • setname:表示集合的名称,可以是任何符合Python 命名跪着的标识符。
  • element 1,element 2,element 3,...,element n:表示集合中的元素,个数没有限制,只要是Python 支持的数据类型就可以。

注意:在创建集合时,如果输入了重复的元素,Python 会自动只保留一个。

例如,有如下面的代码:

set1 = {'水瓶座','双子座','双鱼座','巨蟹座'}
print(set1)
set2 = {2,6,5,1,3,4,9,7,8}
print(set2)
set3 = {'Python',35,('人生苦短','我用Python')}
print(set3)

这段代码将创建以下集合:

{'水瓶座', '双鱼座', '双子座', '巨蟹座'}
{1, 2, 3, 4, 5, 6, 7, 8, 9}
{35, 'Python', ('人生苦短', '我用Python')}

说明:由于Python中的set 集合是无序的,所以每次输出时元素的排列顺序可能都不相同。

场景模拟:某大学的学生选课系统,可选语言有Python 和C 语言。现创建两个集合分别保存选择Python 语言的学生姓名和选择C 语言的学生姓名。

实例12:创建保存学生选课信息的集合

python = {'刘一刀','刘一水','刘三姐','柳条湖'}          # 保存选择Python语言的学生姓名
c = {'刘一水','刘三姐','火车侠','地球超人'} # 保存选择C语言的学生姓名
print('选择Python语言的学生有:',python,'\n') # 输出选择Python语言的学生姓名
print('选择C语言的学生有:',c) # 输出选择C语言的学生姓名

运行后显示的结果如下:

选择Python语言的学生有: {'刘一水', '刘三姐', '柳条湖', '刘一刀'} 

选择C语言的学生有: {'刘一水', '刘三姐', '地球超人', '火车侠'}

2. 使用set() 函数创建

在Python中,可以使用set() 函数将列表、元组等其他可迭代对象转换为集合。set() 函数的语法格式如下:

setname = set(iteration)

参数说明:

  • setname:表示集合名称。
  • iteration:表示要转换为集合的可迭代对象,可以是列表、元组、range 对象等,也可以是字符串。如果是字符串,返回的集合将是包含全部不重复字符的集合。

例如,有如下代码:

set1 = set("命运给予我们的不是失望之酒,而是机会之杯。")
print(set1)
set2 = ([3.55625,5.549698,4.55452,8.54996])
print(set2)
set3 = (('人生苦短','我用Python'))
print(set3)

这段代码将创建以下集合:

{'机', '给', '。', '杯', '的', '我', '予', '不', '命', '是', '酒', '望', '之', '失', ',', '而', '会', '运', '们'}
[3.55625, 5.549698, 4.55452, 8.54996]
('人生苦短', '我用Python')

从上面创建的集合结果中可以看出,在创建集合时,如果出现了重复元素,那么将只保留一个,如在第一个集合中的“是”和“之”都只保留了一个。

注意:在创建空集合中,只能使用set() 实现,而不能使用对“{}”实现,这是因为在Python中,直接使用一对“{}”表示创建一个空字典。

下面将实现实例12修改为使用set() 函数创建保存学生选课信息的集合。修改后的代码如下:

python = set(['刘一刀','刘一水','刘三姐','柳条湖'])          # 保存选择Python语言的学生姓名
print('选择Python语言的学生有:',python,'\n') # 输出选择Python语言的学生姓名
c = set(['刘一水','刘三姐','火车侠','地球超人']) # 保存选择C语言的学生姓名
print('选择C语言的学生有:',c)

执行结果如下:

选择Python语言的学生有: {'刘三姐', '柳条湖', '刘一刀', '刘一水'} 

选择C语言的学生有: {'地球超人', '火车侠', '刘三姐', '刘一水'}

说明:在Python中,创建集合时推荐采用set() 函数实现。

4.5.2 集合的添加和删除

集合是可变序列,所以在创建集合后,还可以对其添加或者删除元素。

1. 向集合中添加元素

向集合中添加元素可以使用add() 方法实现,语法格式如下:

setname.add(element)

参数说明:

  • setname:表示要添加元素的集合。
  • element:表示要添加的元素内容,只能使用字符串、数字及布尔类型的True 或者 False 等,不能使用列表、元组等可迭代对象。

例如,定义一个保存初中课程的集合。代码如下:

jhs = set(['几何','代数','英语','语文','政治','历史','美术'])
jhs.add('体育') # 添加一个元素
print(jhs)

以上代码运行后,将输出如下集合:

{'英语', '代数', '美术', '历史', '几何', '语文', '政治', '体育'} 

2. 从集合中删除元素

在Python中,可以使用del 命令删除整个集合,也可以使用集合的pop() 方法或者remove() 方法删除一个元素,或者使用集合对象的clear() 方法清空集合,即删除集合中的全部元素,使其变为空集合。

例如,下面的代码将分别实现从集合中删除指定元素、删除一个元素和清空集合:

下面的代码将分别实现从集合中删除指定元素、删除一个元素和清空集合:

jhs = set(['几何','代数','英语','语文','政治','历史','美术'])
jhs.remove('代数') # 移除一个元素
print('使用remove()方法移除指定元素后:',jhs)
jhs.pop() # 删除一个元素
print('使用pop()方法移除一个元素后:',jhs)
jhs.clear() # 清空集合
print('使用clear()方法清空集合后:',jhs)

上面代码运行后如下:

使用remove()方法移除指定元素后: {'历史', '几何', '美术', '英语', '政治', '语文'}
使用pop()方法移除一个元素后: {'几何', '美术', '英语', '政治', '语文'}
使用clear()方法清空集合后: set()

注意:使用集合的remove() 方法时,如果指定的内容不存在,将抛出异常。所以在移除指定元素前,最好先判断其是否存在。要判断指定的内容是否存在,可以使用in 关键字实现。例如,使用“'零语'in c”可以判断在c 集合中是否存在“零语”。

实例13:学生更改选学课程

……

4.5.3 集合的交集、并集和差集运算

集合最常用的操作就是进行交集、并集、差集和对称差集运算。进行交集运算时使用“&”符号,进行并集运算时使用“|” 符号,进行差集运算时使用“-” 符号,进行对称差集运算时使用“^” 符号。下面通过一个具体的实例演示如何对集合进行交集、并集和差集运算。

场景模拟:某大学的学生选课系统,学生选课完毕后,老师要对选课结果进行统计。这时,需要知道哪些学生既选择了Python 语言、哪些学生只选择了Python 语言但没有选择C 语言,以及参选与选课的全部学生。

实例14:对选课集合进行交集、并集和差集运算

在文件中定义两个包括4个元素的集合,在根据需要对两个集合进行交集、并集和差集运算,并输出运算结果,代码如下:

python = set(['刘一刀','刘一水','刘三姐','柳条湖'])          # 保存选择Python语言的学生姓名
c = set(['刘一水','刘三姐','火车侠','地球超人']) # 保存选择C语言的学生姓名
print('选择Python语言的学生有:',python,'\n') # 输出选择Python语言的学生姓名
print('选择C语言的学生有:',c) # 输出选择C语言的学生姓名
print('交集运算:',python & c) # 输出既选择了Python语言又选择了C语言的学生姓名
print('并集运算:',python | c) # 输出参与选课的全部学生姓名
print('差集运算:',python - c) # 输出只选择了Python语言但没选择了C语言的学生姓名

在上面的代码中,为了获取既选择了Python 语言又选择了C 语言的学生姓名,对两个集合进行交集运算;为了获取参与选课的全部学生姓名,对两个集合进行并集运算;为了选取只选择了Python 语言但没有选择C 语言的学生名字,对两个集合进行差集运算。

运行实例后,结果如下:

选择Python语言的学生有: {'刘一刀', '刘一水', '刘三姐', '柳条湖'} 

选择C语言的学生有: {'刘一水', '刘三姐', '地球超人', '火车侠'}
交集运算: {'刘一水', '刘三姐'}
并集运算: {'刘一刀', '柳条湖', '刘三姐', '地球超人', '火车侠', '刘一水'}
差集运算: {'刘一刀', '柳条湖'}
>>>

4.6 列表、元组、字典和集合的区别

列表、元组、字典和集合的区别
数据结构 是否可变 是否重复 是否有序 定义符号
列表(list) 可变 可重复 有序 []
元组(tuple) 不可变 可重复 有序 ()
字典(dictionary) 可变 可重复 无序 {key:value}
集合(set) 可变 不可重复 无序 {}