序列是一种常用的数据存储方式,几乎每一种程序设计语言都提供了类似的数据结构。
在Python中序列是最基本的数据结构。它是一块用于存放多个值的连续内存空间。Python中内置了5个常用的序列结构,分别是列表、元组、集合、字典和字符串。
4.1 序列
序列是一块用于存放多个值的连续内存空间,并且按一定顺序排列,每一个值(称为元素)都分配一个数字,称为索引或位置。通过该索引可以取出相应的值。
在Python中,序列结构主要有列表、元组、集合、字典和字符串,对于这些序列结构有以下几个通用的操作。其中,集合和字典不支持索引、切片、相加和相乘操作。
4.1.1 索引
序列中的每一个元素都有一个编号,也称为索引。这个索引是从0开始递增的,即下标为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,当省略该步长时,最后一个冒号也可以省略。
说明:在进行切片操作时,如果指定了步长,那么将按照该步长遍历序列的元素,否则将一个一个遍历序列。
说明:如果想要复制整个序列,可以将start和end参数都省略,但是中间的冒号需要保留。例如,nba[:]就表示复制整个名称为nba的序列。
4.1.3 序列相加
在Python中,支持两种相同类型的序列相加操作,即将两个序列进行连接,不会去除重复的元素,使用加(+)运算符实现。
nba1 = ["德怀特·霍华德","德维恩·韦德","凯里·欧文","保罗·加索尔"]
nba2 = ["迈克尔·乔丹","比尔·拉塞尔","卡里姆·阿布杜尔·贾巴尔","威尔特·张伯伦", "埃尔文·约翰逊","科比·布莱恩特","蒂姆·邓肯","勒布朗·詹姆斯","拉里·伯德", "沙奎尔·奥尼尔"]
print(nba1+nba2)
说明:在进行序列相加时,相同类型的序列是指同为列表、元组、集合等,序列中的元素类型可以不同。
但是不能将列表和元组相加,也不能将列表和字符串相加。例如,下面的代码就是错误的:
num = [7,14,21,28,35,42,49,56,63]
print(num + "输出的数是7的倍数")
4.1.4 乘法
在Python中,使用数字n乘以一个序列会生成新的序列。新序列的内容为原来序列被重复n次的结果。
phone = ["华为Mate 10","Vivo X21"]print(phone * 3)
运行上面的代码,将显示以下内容:
['华为Mate 10', 'Vivo X21', '华为Mate 10', 'Vivo X21', '华为Mate 10', 'Vivo X21']
在进行序列的乘法运算时,还可以实现初始化指定长度列表的功能。例如下面的代码,将创建一个长度为5的列表,列表的每个元素都是None,表示什么都没有。
emptylist = [None]*5print(emptylist)
运行上面的代码,将显示以下内容:
[None, None, None, None, None]
4.1.5 检查某个元素是否是序列的成员
在Python中,可以使用in关键字检查某个元素是否为序列的成员,即检查某个元素是否包含在某个序列中。语法格式如下:
value in sequence
其中,value表示要检查的元素,sequence表示指定的序列。
例如,要检查名称为nba的序列中,是否包含元素“保罗·加索尔”,可以使用下面的代码:
nba = ["德怀特·霍华德","德维恩·韦德","凯里·欧文","保罗·加索尔"]
print("保罗·加索尔" in nba)
运行上面的代码,将显示结果True,表示在序列中存在指定的元素。
另外,在Python中,也可以使用not in关键字实现检查某个元素是否不包含在指定的序列中。例如下面的代码,将显示结果False。
nba = ["德怀特·霍华德","德维恩·韦德","凯里·欧文","保罗·加索尔"]
print("保罗·加索尔" not in nba)
4.1.6 计算序列的长度、最大值和最小值
在Python中,提供了内置函数计算序列的长度、最大值和最小值。分别是:使用len()函数计算序列的长度,即返回序列包含多少个元素;使用max()函数返回序列
中的最大元素;使用min()函数返回序列中的最小元素。
例如,定义一个包括9个元素的列表,并通过len()函数计算列表的长度,可以使用下面的代码:
num = [7,14,21,28,35,42,49,56,63]print("序列num的长度为",len(num))
运行上面的代码,将显示以下结果:
序列num的长度为 9
例如,定义一个包括9个元素的列表,并通过max()函数计算列表的最大元素,可以使用下面的代码:
num = [7,14,21,28,35,42,49,56,63]print("序列",num,"中的最大值为",max(num))
运行上面的代码,将显示以下结果:
序列 [7, 14, 21, 28, 35, 42, 49, 56, 63] 中的最大值为 63
例如,定义一个包括9个元素的列表,并通过min()函数计算列表的最小元素,可以使用下面的代码:
num = [7,14,21,28,35,42,49,56,63]print("序列",num,"中的最小值为",min(num))
运行上面的代码,将显示以下结果:
序列 [7, 14, 21, 28, 35, 42, 49, 56, 63] 中的最小值为 7
除了上面介绍的3个内置函数,Python还提供了如表所示的内置函数。
4.2 列表
它是Python中内置的可变序列。在形式上,列表的所有元素都放在一对中括号“[]”中,两个相邻元素间使用逗号“,”分隔。在内容上,可以将整数、实数、字符串、列表、元组等任何类型的内容放入到列表中,并且同一个列表中,元素的类型可以不同,因为它们之间没有任何关系。由此可见,Python中的列表是非常灵活的,这一点与其他语言是不同的。
4.2.1 列表的创建和删除
在Python中提供了多种创建列表的方法,下面分别进行介绍。
1.使用赋值运算符直接创建列表
同其他类型的Python变量一样,创建列表时,也可以使用赋值运算符“=”直接将一个列表赋值给变量,语法格式如下:
listname = [element 1,element 2,element 3,…,element n]
其中,listname表示列表的名称,可以是任何符合Python命名规则的标识符;“element 1,element 2,element 3,…,element n”表示列表中的元素,个数没有限制,并且只要是Python支持的数据类型就可以。
说明:在使用列表时,虽然可以将不同类型的数据放入到同一个列表中,但是通常情况下,我们不这样做,而是在一个列表中只放入一种类型的数据。这样可以提高程序的可读性。
2.创建空列表
在Python中,也可以创建空列表,例如,要创建一个名称为emptylist的空列表,可以使用下面的代码:
emptylist = []
3.创建数值列表
在Python中,数值列表很常用。
在Python中,可以使用list()函数直接将range()函数循环出来的结果转换为列表。
list()函数的基本语法如下:
list(data)
其中,data表示可以转换为列表的数据,其类型可以是range对象、字符串、元组或者其他可迭代类型的数据。
例如,创建一个10~20之间(不包括20)所有偶数的列表,可以使用下面的代码:list(range(10, 20, 2))
运行上面的代码后,将得到下面的列表:
[10, 12, 14, 16, 18]说明:使用list()函数不仅能通过range对象创建列表,还可以通过其他对象创建列表。
4.删除列表
对于已经创建的列表,不再使用时,可以使用del语句将其删除。语法格式如下:
del listname
其中,listname为要删除列表的名称。说明:del语句在实际开发时,并不常用。因为Python自带的垃圾回收机制会自动销毁不用的列表,所以即使我们不手动将其删除,Python也会自动将其回收。
常见错误:在删除列表前,一定要保证输入的列表名称是已经存在的。
4.2.2 访问列表元素
在Python中,如果想将列表的内容输出也比较简单,可以直接使用print()函数即可。
实际上,列表还可以通过切片操作实现处理列表中的部分元素。
4.2.3 遍历列表
遍历列表中的所有元素是常用的一种操作,在遍历的过程中可以完成查询、处理等功能。
1.直接使用for循环实现
直接使用for循环遍历列表,只能输出元素的值,语法格式如下:for item in listname:
# 输出item
其中,item用于保存获取到的元素值,要输出元素内容时,直接输出该变量即可;listname为列表名称。
2.使用for循环和enumerate()函数实现
使用for循环和enumerate()函数可以实现同时输出索引值和元素内容,语法格式如下:for index,item in enumerate(listname):
# 输出index和item
参数说明:
index:用于保存元素的索引。
item:用于保存获取到的元素值,要输出元素内容时,直接输出该变量即可。
listname为列表名称。
4.2.4 添加、修改和删除列表元素
添加、修改和删除列表元素也称为更新列表。在实际开发时,经常需要对列表进行更新。
1.添加元素
可以通过“+”号将两个序列连接,通过该方法也可以实现为列表添加元素。但是这种方法的执行速度要比直接使用列表对象的append()方法慢,所以建议在实现添加元素时,使用列表对象的append()方法实现。列表对象的append()方法用于在列表的末尾追加元素,语法格式如下:
listname.append(obj)
其中,listname为要添加元素的列表名称,obj为要添加到列表末尾的对象。
多学两招:列表对象除了提供append()方法可以向列表中添加元素,还提供了insert()方法也可以向列表中添加元素。该方法用于向列表的指定位置插入元素。但是由于该方法的执行效率没有append()方法高,所以不推荐这种方法。
上面介绍的是向列表中添加一个元素,如果想要将一个列表中的全部元素添加到另一个列表中,可以使用列表对象的extend()方法实现。extend()方法的语法如下:
listname.extend(seq)
其中,listname为原列表,seq为要添加的列表。语句执行后,seq的内容将追加到listname的后面。
2.修改元素
修改列表中的元素只需要通过索引获取该元素,然后再为其重新赋值即可。
3.删除元素
删除元素主要有两种情况,一种是根据索引删除,另一种是根据元素值进行删除。
根据索引删除
删除列表中的指定元素和删除列表类似,也可以使用del语句实现。所不同的就是在指定列表名称时,换为列表元素。
根据元素值删除
如果想要删除一个不确定其位置的元素(即根据元素值删除),可以使用列表对象的remove()方法实现。例如,要删除列表中内容为“公牛”的元素,可以使用下面的代码:
team = ["火箭","勇士","开拓者","爵士","鹈鹕","马刺","雷霆","森林狼"]
team.remove("公牛")
使用列表对象的remove()方法删除元素时,如果指定的元素不存在,将出现异常信息。
所以在使用remove()方法删除元素前,最好先判断该元素是否存在,改进后的代码如下:
team = ["火箭","勇士","开拓者","爵士","鹈鹕","马刺","雷霆","森林狼"]
value = "公牛" # 指定要移除的元素
if team.count(value)>0: # 判断要删除的元素是否存在
team.remove(value) # 移除指定的元素print(team)
说明:列表对象的count()方法用于判断指定元素出现的次数,返回结果为0时,表示不存在该元素。
4.2.5 对列表进行统计和计算
Python的列表提供了内置的一些函数来实现统计、计算的功能
1.获取指定元素出现的次数
使用列表对象的count()方法可以获取指定元素在列表中的出现次数。基本语法格式如下:
listname.count(obj)
参数说明:
listname:表示列表的名称。
obj:表示要判断是否存在的对象,这里只能进行精确匹配,即不能是元素值的一部分。
返回值:元素在列表中出现的次数。
2.获取指定元素首次出现的下标
使用列表对象的index()方法可以获取指定元素在列表中首次出现的位置(即索引)。基本语法格式如下:
listname.index(obj)
参数说明:
listname:表示列表的名称。
obj:表示要查找的对象,这里只能进行精确匹配。如果指定的对象不存在时,则抛出如图4.14所示的异常。
返回值:首次出现的索引值。
3.统计数值列表的元素和
在Python中,提供了sum()函数用于统计数值列表中各元素的和。
语法格式如下:
sum(iterable[,start])
参数说明:
iterable:表示要统计的列表。
start:表示统计结果是从哪个数开始(即将统计结果加上start所指定的数),是可选参数,如果没有指定,默认值为0。
4.2.6 对列表进行排序
在实际开发时,经常需要对列表进行排序。Python中提供了两种常用的对列表进行排序的方法:使用列表对象的sort()方法,使用内置的sorted()函数。
1.使用列表对象的sort()方法
列表对象提供了sort()方法用于对原列表中的元素进行排序。排序后原列表中的元素顺序将发生改变。列表对象的sort()方法的语法格式如下:
listname.sort(key=None, reverse=False)
参数说明:■ listname:表示要进行排序的列表。■ key:表示指定从每个元素中提取一个用于比较的键(例如,设置“key=str.lower”表示在排序时不区分字母大小写)。■ reverse:可选参数,如果将其值指定为True,则表示降序排列;如果为False,则表示升序排列,默认为升序排列。
使用sort()方法进行数值列表的排序比较简单,但是使用sort()方法对字符串列表进行排序时,采用的规则是先对大写字母排序,然后再对小写字母排序。如果想要对字符串列表进行排序(不区分大小写时),需要指定其key参数。例如,定义一个保存英文字符串的列表,然后应用sort()方法对其进行升序排列,可以使用下面的代码:
char = ['cat','Tom','Angela','pet']
char.sort() # 默认区分字母大小写print("区分字母大小写:",char)
char.sort(key=str.lower) # 不区分字母大小写print("不区分字母大小写:",char)
运行上面的代码,将显示以下内容:
区分字母大小写: ['Angela', 'Tom', 'cat', 'pet']
不区分字母大小写: ['Angela', 'cat', 'pet', 'Tom']说明:采用sort()方法对列表进行排序时,对中文支持不好。排序的结果与我们常用的音序排序法或者笔画排序法都不一致。如果需要实现对中文内容的列表排序,还需要重新编写相应的方法进行处理,不能直接使用sort()方法。
2.使用内置的sorted()函数实现
在Python中,提供了一个内置的sorted()函数,用于对列表进行排序。使用该函数进行排序后,原列表的元素顺序不变。sorted()函数的语法格式如下:
sorted(iterable, key=None, reverse=False)
参数说明:■ iterable:表示要进行排序的列表名称。■ key:表示指定从每个元素中提取一个用于比较的键(例如,设置“key=str.lower”表示在排序时不区分字母大小写)。■ reverse:可选参数,如果将其值指定为True,则表示降序排列;如果为False,则表示升序排列,默认为升序排列。
说明:列表对象的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)
执行结果如下:
生成的随机数为: [38, 12, 28, 26, 58, 67, 100, 41, 97, 15]
(2)根据列表生成指定需求的列表,语法格式如下:
newlist = [Expression for var in list]
参数说明:■ newlist:表示新生成的列表名称。■ Expression:表达式,用于计算新列表的元素。■ var:变量,值为后面列表的每个元素值。■ list:用于生成新列表的原列表。
例如,定义一个记录商品价格的列表,然后应用列表推导式生成一个将全部商品价格打五折的列表,具体代码如下:
price = [1200,5330,2988,6200,1998,8888]
sale = [int(x*0.5) for x in price]print("原价格:",price)print("打五折的价格:",sale)
执行结果如下:
原价格: [1200, 5330, 2988, 6200, 1998, 8888]
打五折的价格: [600, 2665, 1494, 3100, 999, 4444]
(3)从列表中选择符合条件的元素组成新的列表,语法格式如下:
newlist = [Expression for var in list if condition]
参数说明:■ newlist:表示新生成的列表名称。■ Expression:表达式,用于计算新列表的元素。■ var:变量,值为后面列表的每个元素值。■ list:用于生成新列表的原列表。■ condition:条件表达式,用于指定筛选条件。
例如,定义一个记录商品价格的列表,然后应用列表推导式生成一个商品价格高于5000元的列表,具体代码如下:
price = [1200,5330,2988,6200,1998,8888]
sale = [x for x in price if x>5000]print("原列表:",price)print("价格高于5000的:",sale)
执行结果如下:
原列表: [1200, 5330, 2988, 6200, 1998, 8888]
价格高于5000的: [5330, 6200, 8888]
4.2.8 二维列表的使用
1.直接定义二维列表
在Python中,二维列表是包含列表的列表,即一个列表的每一个元素又都是一个列表。例如,下面就是一个二维列表:
[['千', '山', '鸟', '飞', '绝'],
['万', '径', '人', '踪', '灭'],
['孤', '舟', '蓑', '笠', '翁'],
['独', '钓', '寒', '江', '雪']]
在创建二维列表时,可以直接使用下面的语法格式进行定义:
listname = [[元素11, 元素12, 元素13, …, 元素1n],
[元素21, 元素22, 元素23, …, 元素2n],
…,
[元素n1, 元素n2, 元素n3, …, 元素nn]]
参数说明:■ listname:表示生成的列表名称。■ [元素11, 元素12, 元素13, …, 元素1n]:表示二维列表的第一行,也是一个列表。其中“元素11,元素12,…元素1n”代表第一行中的列。■ [元素21, 元素22, 元素23, …, 元素2n]:表示二维列表的第二行。■ [元素n1, 元素n2, 元素n3, …, 元素nn]:表示二维列表的第n行。
2.使用嵌套的for循环创建
创建二维列表,可以使用嵌套的for循环实现。例如,创建一个包含4行5列的二维列表,可以使用下面的代码:
arr = [] # 创建一个空列表for i in range(4):
arr.append([]) # 在空列表中再添加一个空列表 for j in range(5):
arr[i].append(j) # 为内层列表添加元素
上面代码在执行后,将创建以下二维列表:
[[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)]
上面代码在执行后,将创建以下二维列表:
[[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]
下面通过一个具体实例演示二维列表的应用。
实例 使用二维列表输出不同版式的古诗
在IDLE中创建一个名称为printverse.py的文件,然后在该文件中首先定义4个字符串,内容为柳宗元的《江雪》中的诗句,并定义一个二维列表,然后应用嵌套的for循环将古诗以横版方式输出,再将二维列表进行逆序排列,最后应用嵌套的for循环将古诗以竖版方式输出,代码如下:
str1 = "千山鸟飞绝"
str2 = "万径人踪灭"03 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中另一个重要的序列结构,与列表类似,也是由一系列按特定顺序排列的元素组成,但是它是不可变序列。因此,元组也可以称为不可变的列表。在形式上,元组的所有元素都放在一对“()”中,两个相邻元素间使用“,”分隔。在内容上,可以将整数、实数、字符串、列表、元组等任何类型的内容放入到元组中,并且在同一个元组中,元素的类型可以不同,因为它们之间没有任何关系。通常情况下,元组用于保存程序中不可修改的内容。说明:从元组和列表的定义上看,这两种结构比较相似,二者之间的主要区别为:元组是不可变序列,列表是可变序列。即元组中的元素不可以单独修改,而列表则可以任意修改。
4.3.1 元组的创建和删除
1.使用赋值运算符直接创建元组
同其他类型的Python变量一样,创建元组时,也可以使用赋值运算符“=”直接将一个元组赋值给变量。语法格式如下:
tuplename = (element 1,element 2,element 3,…,element n)
其中,tuplename表示元组的名称,可以是任何符合Python命名规则的标识符;element 1、element 2、element 3、element n表示元组中的元素,个数没有限制,并且只要为Python支持的数据类型就可以。注意:创建元组的语法与创建列表的语法类似,只是创建列表时使用的是“[]”,而创建元组时使用的是“()”。
在Python中,元组使用一对小括号将所有的元素括起来,但是小括号并不是必须的,只要将一组值用逗号分隔开来,Python就可以视其为元组。例如,下面的代码定义的也是元组:
ukguzheng = "渔舟唱晚","高山流水","出水莲","汉宫秋月"
如果要创建的元组只包括一个元素,则需要在定义元组时,在元素的后面加一个逗号“,”。例如,下面的代码定义的就是包括一个元素的元组:
verse1 = ("一片冰心在玉壶",)
说明:在Python中,可以使用type()函数测试变量的类型。
2.创建空元组
在Python中,也可以创建空元组,例如,创建一个名称为emptytuple的空元组,可以使用下面的代码:
emptytuple = ()
空元组可以应用在为函数传递一个空值或者返回空值时。例如,定义一个函数必须传递一个元组类型的值,而我们还不想为它传递一组数据,那么就可以创建一个空元组传递给它。
3.创建数值元组
在Python中,可以使用tuple()函数直接将range()函数循环出来的结果转换为数值元组。
tuple()函数的基本语法如下:
tuple(data)
其中,data表示可以转换为元组的数据,其类型可以是range对象、字符串、元组或者其他可迭代类型的数据。
说明:使用tuple()函数不仅能通过range对象创建元组,还可以通过其他对象创建元组。
4.删除元组
对于已经创建的元组,不再使用时,可以使用del语句将其删除。语法格式如下:
del tuplename
其中,tuplename为要删除元组的名称。说明:del语句在实际开发时,并不常用。因为Python自带的垃圾回收机制会自动销毁不用的元组,所以即使我们不手动将其删除,Python也会自动将其回收。
4.3.2 访问元组元素
在Python中,如果想将元组的内容输出也比较简单,可以直接使用print()函数即可。
如果不想要输出全部的元素,也可以通过元组的索引获取指定的元素。例如,要获取元组untitle中索引为0的元素,可以使用下面的代码:print(untitle[0])
另外,对于元组也可以采用切片方式获取指定的元素。例如,要访问元组untitle中前3个元素,可以使用下面的代码:print(untitle[:3])
同列表一样,元组也可以使用for循环进行遍历。
另外,元组还可以使用for循环和enumerate()函数结合进行遍历。
说明:enumerate()函数用于将一个可遍历的数据对象(如列表或元组)组合为一个索引序列,同时列出数据和数据下标,一般在for循环中使用。
4.3.3 修改元组元素
元组是不可变序列,所以我们不能对它的单个元素值进行修改。但是元组也不是完全不能修改。我们可以对元组进行重新赋值。
另外,还可以对元组进行连接组合。例如,可以使用下面的代码实现在已经存在的元组结尾处添加一个新元组。
ukguzheng = ('蓝山','卡布奇诺','曼特宁','摩卡')
print("原元组:",ukguzheng)
ukguzheng = ukguzheng + ('麝香猫','哥伦比亚')
print("组合后:",ukguzheng)
注意:在进行元组连接时,连接的内容必须都是元组。不能将元组和字符串或者列表进行连接。例如,下面的代码就是错误的。
ukguzheng = ('蓝山','卡布奇诺','曼特宁','摩卡')
ukguzheng = ukguzheng + ['麝香猫','哥伦比亚']常见错误:在进行元组连接时,如果要连接的元组只有一个元素时,一定不要忘记后面的逗号。例如,使用下面的代码将产生如图4.21所示的错误。
ukguzheng = ('蓝山','卡布奇诺','曼特宁','摩卡')
ukguzheng = ukguzheng + ('麝香猫')
.3.4 元组推导式
使用元组推导式可以快速生成一个元组,它的表现形式和列表推导式类似,只是将列表推导式中的“[]”修改为“()”。
使用元组推导式生成的结果并不是一个元组或者列表,而是一个生成器对象,这一点和列表推导式是不同的。要使用该生成器对象可以将其转换为元组或者列表。其中,转换为元组使用tuple()函数,而转换为列表则使用list()函数。
要使用通过元组推导器生成的生成器对象,还可以直接通过for循环遍历或者直接使用__next__()方法进行遍历。说明:在Python 2.x中,__next__()方法对应的方法为next()方法,也是用于遍历生成器对象的。
4.3.5 元组与列表的区别
元组和列表都属于序列,而且它们又都可以按照特定顺序存放一组元素,类型又不受限制,只要是Python支持的类型都可以。那么它们之间有什么区别呢?
列表类似于我们用铅笔在纸上写下自己喜欢的歌词,写错了还可以擦掉;而元组则类似于用钢笔写下的歌词,写错了就擦不掉了,除非换一张纸重写。
列表和元组的区别主要体现在以下几个方面:
列表属于可变序列,它的元素可以随时修改或者删除;元组属于不可变序列,其中的元素不可以修改,除非整体替换。
列表可以使用append()、extend()、insert()、remove()和pop()等方法实现添加和修改列表元素,而元组没有这几个方法,所以不能向元组中添加和修改元素。同样,元组也不能删除元素。
列表可以使用切片访问和修改列表中的元素。元组也支持切片,但是它只支持通过切片访问元组中的元素,不支持修改。
元组比列表的访问和处理速度快,所以当只是需要对其中的元素进行访问,而不进行任何修改时,建议使用元组。
列表不能作为字典的键,而元组则可以。
4.4 字典
在Python中,字典与列表类似,也是可变序列,不过与列表不同,它是无序的可变序列,保存的内容是以“键-值对”的形式存放的。
字典的主要特征如下:
■ 通过键而不是通过索引来读取
字典有时也称为关联数组或者散列表(hash)。它是通过键将一系列的值联系起来的,这样就可以通过键从字典中获取指定项,但不能通过索引来获取。
■ 字典是任意对象的无序集合
字典是无序的,各项是从左到右随机排序的,即保存在字典中的项没有特定的顺序。这样可以提高查找效率。
■ 字典是可变的,并且可以任意嵌套
字典可以在原处增长或者缩短(无须生成一个副本)。并且它支持任意深度的嵌套(即它的值可以是列表或者其他的字典)。
■ 字典中的键必须唯一
不允许同一个键出现两次,如果出现两次,则后一个值会被记住。
■ 字典中的键必须不可变
字典中的键是不可变的,所以可以使用数字、字符串或者元组,但不能使用列表。说明:Python中的字典相当于Java或者C++中的Map对象。
4.4.1 字典的创建和删除
定义字典时,每个元素都包含两个部分“键”和“值”。
创建字典时,在“键”和“值”之间使用冒号分隔,相邻两个元素使用逗号分隔,所有元素放在一对“{}”中。语法格式如下:
dictionary = {'key1':'value1', 'key2':'value2', …, 'keyn':'valuen',}
参数说明:
■ dictionary:表示字典名称。
■ key1、key2…keyn:表示元素的键,必须是唯一的,并且不可变,例如,可以是字符串、数字或者元组。
■ value1、value2…valuen:表示元素的值,可以是任何数据类型,不是必须唯一的。
同列表和元组一样,也可以创建空字典。在Python中,可以使用下面两种方法创建空字典:
dictionary = {}
或者
dictionary = dict()
Python中的dict()方法除了可以创建一个空字典外,还可以通过已有数据快速创建字典。主要表现为以下两种形式:
1.通过映射函数创建字典
通过映射函数创建字典的语法如下:
dictionary = dict(zip(list1,list2))
参数说明:
dictionary:表示字典名称。
zip()函数:用于将多个列表或元组对应位置的元素组合为元组,并返回包含这些内容的zip对象。如果想获取元组,可以将zip对象使用tuple()函数转换为元组;如果想获取列表,则可以使用list()函数将其转换为列表。说明:在Python 2.x中,zip()函数返回的内容为包含元组的列表。
list1:一个列表,用于指定要生成字典的键。
list2:一个列表,用于指定要生成字典的值。如果list1和list2的长度不同,则与最短的列表长度相同。
2.通过给定的关键字参数创建字典
通过给定的关键字参数创建字典的语法如下:
dictionary = dict(key1=value1,key2=value2,…,keyn=valuen)
参数说明:
dictionary:表示字典名称。
key1,key2,…,keyn:表示参数名,必须是唯一的,并且符合Python标识符的命名规则。该参数名会转换为字典的键。
value1,value2,…,valuen:表示参数值,可以是任何数据类型,不必须唯一。该参数值将被转换为字典的值。
在Python中,还可以使用dict对象的fromkeys()方法创建值为空的字典,语法如下:
dictionary = dict.fromkeys(list1)
参数说明:■ dictionary:表示字典名称。■ list1:作为字典的键的列表。
另外,还可以通过已经存在的元组和列表创建字典。例如,创建一个保存名字的元组和保存星座的列表,通过它们创建一个字典,可以使用下面的代码:
name_tuple = ('绮梦','冷伊一', '香凝', '黛兰') # 作为键的元组
sign = ['水瓶座','射手座','双鱼座','双子座'] # 作为值的列表
dict1 = {name_tuple:sign} # 创建字典print(dict1)
执行结果如下:
{('绮梦', '冷伊一', '香凝', '黛兰'): ['水瓶座', '射手座', '双鱼座', '双子座']}
同列表和元组一样,不再需要的字典也可以使用del命令删除整个字典。例如,通过下面的代码即可将已经定义的字典删除。del dictionary
另外,如果只是想删除字典的全部元素,可以使用字典对象的clear()方法实现。执行clear()方法后,原字典将变为空字典。例如,下面的代码将清除字典的全部元素。
dictionary.clear()
除了上面介绍的方法可以删除字典元素,还可以使用字典对象的pop()方法删除并返回指定“键”的元素,以及使用字典对象的popitem()方法删除并返回字典中的一个元素。
4.4.2 通过键值对访问字典
在Python中,如果想将字典的内容输出也比较简单,可以直接使用print()函数。
打印实例中定义的dictionary字典,则可以使用下面的代码:
print(dictionary)
但是,在使用字典时,很少直接输出它的内容。一般需要根据指定的键得到相应的结果。在Python中,访问字典的元素可以通过下标的方式实现,与列表和元组不同,这里的下标不是索引号,而是键。
在使用该方法获取指定键的值时,如果指定的键不存在,就会抛出异常。
在实际开发中,我们可能不知道当前存在什么键,所以需要避免该异常的产生。具体的解决方法是使用if语句对不存在的情况进行处理,即设置一个默认值。例如,可以将上面的代码修改为以下内容:print("冷伊的星座是:",dictionary['冷伊'] if '冷伊' in dictionary else '我的字典里没有此人')
另外,Python中推荐的方法是使用字典对象的get()方法获取指定键的值,语法格式如下:
dictionary.get(key[,default])
参数说明:■ dictionary:为字典对象,即要从中获取值的字典。■ key:为指定的键。■ default:为可选项,用于指定当指定的“键”不存在时,返回一个默认值,如果省略,则返回None。
说明:为了解决在获取指定键的值时,因不存在该键而导致抛出异常,可以为get()方法设置默认值,这样当指定的键不存在时,得到结果就是指定的默认值。例如,将上面的代码修改为以下内容。print("冷伊的星座是:",dictionary.get('冷伊','我的字典里没有此人'))
将得到以下结果:
冷伊的星座是: 我的字典里没有此人
4.4.3 遍历字典
字典是以“键-值对”的形式存储数据的,所以需要通过这些“键-值对”进行获取。Python提供了遍历字典的方法,通过遍历可以获取字典中的全部“键-值对”。
使用字典对象的items()方法可以获取字典的“键-值对”列表,语法格式如下:
dictionary.items()
其中,dictionary为字典对象;返回值为可遍历的(键-值对)的元组列表。想要获取到具体的“键-值对”,可以通过for循环遍历该元组列表。
通过items()方法获取“键-值对”的元组列表,
for item in dictionary.items():
获取具体的每个键和值
for key,value in dictionary.items():
说明:在Python中,字典对象还提供了values()方法和keys()方法,用于返回字典的“值”和“键”列表,它们的使用方法同items()方法类似,也需要通过for循环遍历该字典列表,获取对应的值和键。
4.4.4 添加、修改和删除字典元素
由于字典是可变序列,所以可以随时在字典中添加“键-值对”。向字典中添加元素的语法格式如下:
dictionary[key] = value
参数说明:■ dictionary:表示字典名称。■ key:表示要添加元素的键,必须是唯一的,并且不可变,例如可以是字符串、数字或者元组。■ value:表示元素的值,可以是任何数据类型,不是必须唯一的。
由于在字典中,“键”必须是唯一的,如果新添加元素的“键”与已经存在的“键”重复,那么将使用新的“值”替换原来该“键”的值,这也相当于修改字典的元素。
当字典中的某一个元素不需要时,可以使用del命令将其删除。
注意:当删除一个不存在的键时,将抛出如图4.27所示的异常。
4.4.5 字典推导式
使用字典推导式可以快速生成一个字典,它的表现形式和列表推导式类似。例如,我们可以使用下面的代码生成一个包含4个随机数的字典,其中字典的键使用数字表示。import random # 导入random标准库
randomdict = {i:random.randint(10,100) for i in range(1,5)}print("生成的字典为:",randomdict)
生成的字典为: {1: 21, 2: 85, 3: 11, 4: 65}
另外,使用字典推导式也可根据列表生成字典。例如,可以将实例09修改为通过字典推导式生成字典。
实例11 应用字典推导式实现根据名字和星座创建一个字典
在IDLE中创建一个名称为sign_create.py的文件,然后在该文件中,定义两个包括4个元素的列表,再应用字典推导式将前两个列表转换为对应的字典,并且输出该字典,代码如下:
name = ['绮梦','冷伊一','香凝','黛兰'] # 作为键的列表
sign = ['水瓶','射手','双鱼','双子'] # 作为值的列表
dictionary = {i:j+'座' for i,j in zip(name,sign)} # 使用列表推导式生成字典
print(dictionary) # 输出转换后字典
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会自动只保留一个。
说明:由于Python中的set集合是无序的,所以每次输出时元素的排列顺序可能都不相同。
2.使用set()函数创建
在Python中,可以使用set()函数将列表、元组等其他可迭代对象转换为集合。set()函数的语法格式如下:
setname = set(iteration)
参数说明:■ setname:表示集合名称。■ iteration:表示要转换为集合的可迭代对象,可以是列表、元组、range对象等,也可以是字符串。如果是字符串,返回的集合将是包含全部不重复字符的集合。
注意:在创建空集合时,只能使用set()实现,而不能使用一对“{}”实现,这是因为在Python中,直接使用一对“{}”表示创建一个空字典。
说明:在Python中,创建集合时推荐采用set()函数实现。
4.5.2 集合的添加和删除
集合是可变序列,所以在创建集合后,还可以对其添加或者删除元素。
1.向集合中添加元素
向集合中添加元素可以使用add()方法实现,语法格式如下:
setname.add(element)
参数说明:■ setname:表示要添加元素的集合。■ element:表示要添加的元素内容,只能使用字符串、数字、布尔类型的True或者False及元组等不可变对象,不能使用列表、字典等可变对象。
2.从集合中删除元素
在Python中,可以使用del命令删除整个集合,也可以使用集合的pop()方法或者remove()方法删除一个元素,或者使用集合对象的clear()方法清空集合,即删除集合中的全部元素,使其变为空集合。
注意:使用集合的remove()方法时,如果指定的内容不存在,将抛出如图4.30所示的异常。所以在移除指定元素前,最好先判断其是否存在。要判断指定的内容是否存在,可以使用in关键字实现。例如,使用“‘零语’in c”可以判断在c集合中是否存在“零语”。
4.5.3 集合的交集、并集和差集运算
集合最常用的操作就是进行交集、并集、差集和对称差集运算。进行交集运算时使用“&”符号,进行并集运算时使用“|”符号,进行差集运算时使用“-”符号,进行对称差集运算时使用“^”符号。
实例14 对选课集合进行交集、并集和差集运算
在IDLE中创建一个名称为section_operate.py的文件,然后在该文件中定义两个包括4个元素的集合,再根据需要对两个集合进行交集、并集和差集运算,并输出运算结果,代码如下:
python = set(['绮梦','冷伊一','香凝','梓轩']) # 保存选择Python语言的学生姓名
c = set(['冷伊一','零语','梓轩','圣博']) # 保存选择C语言的学生姓名
print('选择Python语言的学生有:',python) # 输出选择Python语言的学生姓名
print('选择C语言的学生有:',c) # 输出选择C语言的学生姓名
print('交集运算:',python & c) # 输出既选择了Python语言又选择了C语言的学生姓名
print('并集运算:',python | c) # 输出参与选课的全部学生姓名
print('差集运算:',python - c) # 输出只选择了Python语言但没有选择C语言的学生姓名
4.6 列表、元组、字典和集合的区别
在4.2~4.5节介绍了序列中的列表、元组、字典和集合的应用,下面通过表4.2对这几个数据序列进行比较。
4.7小结
本章首先简要介绍了Python中的序列及序列的常用操作,然后重点介绍了Python中的列表和元组。其中,元组可以理解为被上了“枷锁”的列表,即元组中的元素不可以修改;接下来又介绍了Python中的字典,字典和列表有些类似,区别是字典中的元素是由“键-值对”组成的;最后介绍了Python中的集合,对于集合的主要作用就是去掉重复的元素。