我心中的王者:Python-第6章 列表(List)
列表(list)是Python的一种可以更改内容的数据类型,它是由一系列元素所组成的序列。如果现在我们要设计班上同学的成绩表,班上有50位同学,可能需要设计50个变量,这是一件麻烦的事。如果学校单位要设计所有学生的数据库,学生人数有1000人,需要1000个变量,这似乎是不可能的事。Python的列表数据类型,可以只用一个变量,解决这方面的问题,要存取时用列表名称加上索引值即可,这也是本章的主题。
相信阅读至此章节,读者已经对Python有一些基础了解了,这章笔者也将讲解简单的面向对象(Object Oriented)观念,同时指导读者学习利用Python所提供的内置资源,未来将一步一步带领读者迈向高手之路。
6-1 认识列表
其实在其他程序语言,相类似的功能是称数组(array)。不过,Python的列表功能除了可以存储相同数据类型,例如,整数、浮点数、字符串,也可以存储不同数据类型,例如,列表内同时含有整数、浮点数和字符串。甚至一个列表也可以内含其他列表(将在6-7节解说)或是字典(dict)(将在9-3节解说),因此,Python可以工作的能力,将比其他程序语言强大。
6-1-1 列表的基本定义
定义列表的语法格式如下:
name_list = [元素1, … , 元素n]# name_list是假设的列表名称
基本上列表的每一个数据称元素,这些元素放在中括号[ ]内,彼此用逗号“,”隔开。如果要打印列表内容,可以使用print( )函数,将列表名称当作变量名称即可。
实例1: NBA球员James前5场比赛得分,分别是23、19、22、31、18,可以用下列方式定义列表。
实例2: 为所销售的水果,苹果、香蕉、橘子建立列表,可以用下列方式定义列表。
在定义字符串时,元素内容也可以使用中文。
实例3:为所销售的水果,苹果、香蕉、橘子建立中文元素的列表,可以用下列方式定义列表。
实例4: 在实例1的James列表,增加第1个元素,放他的全名。
程序实例ch6_1.py: 定义列表同时打印,最后使用type( )列出列表数据类型。
# ch6_1.py
james = [23, 19, 22, 31, 18] # 定义james列表
print("打印james列表", james)
James = ['Lebron James',23, 19, 22, 31, 18] # 定义James列表
print("打印James列表", James)
fruits = ['apple', 'banana', 'orange'] # 定义fruits列表
print("打印fruits列表", fruits)
cfruits = ['苹果', '香蕉', '橘子'] # 定义cfruits列表
print("打印cfruits列表", cfruits)
ielts = [5.5, 6.0, 6.5] # 定义IELTS成绩列表
print("打印IELTS成绩", ielts)
# 列出列表数据型态
print("列表james数据型态是: ",type(james))
执行结果
打印james列表 [23, 19, 22, 31, 18]
打印James列表 ['Lebron James', 23, 19, 22, 31, 18]
打印fruits列表 ['apple', 'banana', 'orange']
打印cfruits列表 ['苹果', '香蕉', '橘子']
打印IELTS成绩 [5.5, 6.0, 6.5]
列表james数据型态是: <class 'list'>
6-1-2 读取列表元素
我们可以用列表名称与索引读取列表元素的内容,在Python中元素是从索引值0开始配置。所以如果是列表的第一个元素,索引值是0,第二个元素索引值是1,其他依此类推,如下所示:
name_list[i] # 读取索引i的列表元素
程序实例ch6_2.py: 读取列表元素的应用。
# ch6_2.py
james = [23, 19, 22, 31, 18] # 定义james列表
print("打印james第1场得分", james[0])
print("打印james第2场得分", james[1])
print("打印james第3场得分", james[2])
print("打印james第4场得分", james[3])
print("打印james第5场得分", james[4])
执行结果
打印james第1场得分 23
打印james第2场得分 19
打印james第3场得分 22
打印james第4场得分 31
打印james第5场得分 18
上述程序经过第2行的定义后,列表索引值的解释如下:
所以程序第3行至第7行,可以得到上述执行结果。其实我们也可以将2-9节等号多重指定观念应用在列表。
程序实例ch6_2_1.py: 一个传统处理列表元素内容方式,与Python多重指定观念的应用。
# ch6_2_1.py
james = [23, 19, 22, 31, 18] # 定义james列表
# 传统设计方式
game1 = james[0]
game2 = james[1]
game3 = james[2]
game4 = james[3]
game5 = james[4]
print("打印james各场次得分", game1, game2, game3, game4, game5)
# Python高手好的设计方式
game1, game2, game3, game4, game5 = james
print("打印james各场次得分", game1, game2, game3, game4, game5)
执行结果
打印james各场次得分 23 19 22 31 18
打印james各场次得分 23 19 22 31 18
上述程序第11行让整个Python设计简洁许多,这是Python高手常用的程序设计方式,在上述设计中第11行的多重指定变数的数量需与列表元素的个数相同,否则会有错误产生。
6-1-3 列表切片(list slices)
在设计程序时,常会需要取得列表前几个元素、后几个元素、某区间元素或是依照一定规则排序的元素,所取得的系列元素也可称子列表,这个观念称列表切片(list slices),此时可以用下列方法。
程序实例ch6_2_2.py: 列出特定区间球员的得分子列表。
# ch6_2_2.py
james = [23, 19, 22, 31, 18] # 定义james列表
print("打印james第1-3场得分", james[0:3])
print("打印james第2-4场得分", james[1:4])
print("打印james第1,3,5场得分", james[0:6:2])
执行结果
打印james第1-3场得分 [23, 19, 22]
打印james第2-4场得分 [19, 22, 31]
打印james第1,3,5场得分 [23, 22, 18]
程序实例ch6_3.py: 列出球队前3名队员、从索引1到最后队员与后3名队员子列表。
# ch6_3.py
warriors = ['Curry', 'Durant', 'Iquodala', 'Bell', 'Thompson']
first3 = warriors[:3]
print("前3名球员",first3)
n_to_last = warriors[1:]
print("球员索引1到最后",n_to_last)
last3 = warriors[-3:]
print("后3名球员",last3)
执行结果
前3名球员 ['Curry', 'Durant', 'Iquodala']
球员索引1到最后 ['Durant', 'Iquodala', 'Bell', 'Thompson']
后3名球员 ['Iquodala', 'Bell', 'Thompson']
6-1-4 列表索引值是-1
在列表使用中,如果索引值是-1,代表是最后一个列表元素。
程序实例ch6_4.py: 列表索引值是-1的应用,由下列执行结果可以得到各列表的最后一个元素了。
# ch6_4.py
warriors = ['Curry', 'Durant', 'Iquodala', 'Bell', 'Thompson']
print("最后一名球员",warriors[-1])
james = [23, 19, 22, 31, 18]
print("最后一场得分",james[-1])
mixs = [9, 20.5, 'DeepStone']
print("最后一笔元素",mixs[-1])
执行结果
最后一名球员 Thompson
最后一场得分 18
最后一笔元素 DeepStone
其实在Python中索引-1代表最后1个元素,-2代表最后第2个元素,其他负索引观念可依次类推,可参考下列实例。
程序实例ch6_4_1.py: 使用负索引列出warriors列表内容。
# ch6_4_1.py
warriors = ['Curry', 'Durant', 'Iquodala', 'Bell', 'Thompson']
print(warriors[-1],warriors[-2],warriors[-3],warriors[-4],warriors[-5])
执行结果
Thompson Bell Iquodala Durant Curry
6-1-5 列表统计资料、最大值max( )、最小值min( )、总和sum( )
Python有内置一些执行统计运算的函数,如果列表内容全部是数值则可以使用max( )函数获得列表的最大值,min( )函数可以获得列表的最小值,sum( )函数可以获得列表的总和。如果列表内容全部是字符或字符串则可以使用max( )函数获得列表的unicode码值的最大值,min( )函数可以获得列表的unicode码值最小值。sum( )则不可使用在列表元素为非数值情况。
程序实例ch6_5.py: 计算james球员5场的最高得分、最低得分和5场的得分总计。
# ch6_5.py
james = [23, 19, 22, 31, 18] # 定义james的5场比赛得分
print("最高得分 = ", max(james))
print("最低得分 = ", min(james))
print("得分总计 = ", sum(james))
执行结果
最高得分 = 31
最低得分 = 18
得分总计 = 113
上述我们很快获得了统计信息,各位可能会想,当列表内含有字符串,如程序实例ch6_1.py的James列表,这个列表第一个元素是字符串,如果这时仍然直接用max(James)会有错误的。
碰上这类的字符串我们可以使用6-1-2节方式,用切片方式处理,如下所示。
程序实例ch6_6.py: 重新设计ch6_5.py,但是使用James列表。
# ch6_6.py
James = ['Lebron James', 23, 19, 22, 31, 18] # 定义james的5场比赛得分
print("最高得分 = ", max(James[1:6]))
print("最低得分 = ", min(James[1:6]))
print("得分总计 = ", sum(James[1:6]))
执行结果
最高得分 = 31
最低得分 = 18
得分总计 = 113
6-1-6 列表个数len( )
程序设计时,可能会增加元素,也有可能会删除元素,时间久了即使是程序设计师也无法得知列表内剩余多少元素,此时可以借用本小节的len( )函数,这个函数可以获得列表的元素个数。
程序实例ch6_7.py: 重新设计ch6_5.py,增加场次数据。
# ch6_7.py
james = [23, 19, 22, 31, 18] # 定义james的5场比赛得分
games = len(james) # 获得场次数据
print("经过 %d 比赛最高得分 = " % games, max(james))
print("经过 %d 比赛最低得分 = " % games, min(james))
print("经过 %d 比赛得分总计 = " % games, sum(james))
执行结果
经过 5 比赛最高得分 = 31
经过 5 比赛最低得分 = 18
经过 5 比赛得分总计 = 113
6-1-7 更改列表元素的内容
可以使用列表名称和索引值更改列表元素的内容。
程序实例ch6_8.py: 修改james第5场比赛分数。
# ch6_8.py
james = [23, 19, 22, 31, 18] # 定义james的5场比赛得分
print("旧的James比赛分数", james)
james[4] = 28
print("新的James比赛分数", james)
执行结果
旧的James比赛分数 [23, 19, 22, 31, 18]
新的James比赛分数 [23, 19, 22, 31, 28]
这个观念可以用在更改整数数据也可以修改字符串数据。
程序实例ch6_9.py: 一家汽车经销商原本可以销售Toyota、Nissan、Honda,现在Nissan销售权被回收,改成销售Ford,可用下列方式设计销售品牌。
# ch6_9.py
cars = ['Toyota', 'Nissan', 'Honda']
print("旧汽车销售品牌", cars)
cars[1] = 'Ford' # 更改第二笔元素内容
print("新汽车销售品牌", cars)
执行结果
旧汽车销售品牌 ['Toyota', 'Nissan', 'Honda']
新汽车销售品牌 ['Toyota', 'Ford', 'Honda']
6-1-8 列表的相加
Python是允许列表相加的,相当于将列表结合。
程序实例ch6_10.py: 一家汽车经销商原本可以销售Toyota、Nissan、Honda,现在并购一家销售Audi、BMW的经销商,可用下列方式设计销售品牌。
# ch6_10.py
cars1 = ['Toyota', 'Nissan', 'Honda']
print("旧汽车销售品牌", cars1)
cars2 = ['Audi', 'BMW']
cars1 += cars2
print("新汽车销售品牌", cars1)
执行结果
旧汽车销售品牌 ['Toyota', 'Nissan', 'Honda']
新汽车销售品牌 ['Toyota', 'Nissan', 'Honda', 'Audi', 'BMW']
程序实例ch6_11.py: 整数列表相加的实例。
# ch6_11.py
num1 = [1, 3, 5]
num2 = [2, 4, 6]
num3 = num1 + num2 # 字符串为主的列表相加
print(num3)
执行结果
[1, 3, 5, 2, 4, 6]
6-1-9 列表乘以一个数字
如果将列表乘以一个数字,这个数字相当于是列表元素重复次数。
程序实例ch6_12.py :将列表乘以数字的应用。
# ch6_12.py
cars = ['toyota', 'nissan', 'honda']
nums = [1, 3, 5]
carslist = cars * 3 # 列表乘以数字
print(carslist)
numslist = nums * 5 # 列表乘以数字
print(numslist)
执行结果
['toyota', 'nissan', 'honda', 'toyota', 'nissan', 'honda', 'toyota', 'nissan', 'honda']
[1, 3, 5, 1, 3, 5, 1, 3, 5, 1, 3, 5, 1, 3, 5]
6-1-10 列表元素的加法运作
既然我们可以读取列表内容,其实就可以使用相同的观念操作列表内的元素数据。
程序实例ch6_13.py: 建立Lebron James和Kevin Love在比赛的得分列表,然后利用列表元素加法运作,列出2个人在第四场比赛的得分总和。
# ch6_13.py
James = ['Lebron James',23, 19, 22, 31, 18] # 定义James列表
Love = ['Kevin Love',20, 18, 30, 22, 15] # 定义Love列表
game3 = James[4] + Love[4]
LKgame = James[0] + ' 和 ' + Love[0] + '第四场总得分 = '
print(LKgame, game3)
执行结果
Lebron James 和 Kevin Love第四场总得分 = 53
需要注意,由第2行列表定义可知,James[0]是指“Lebron James”,James[1]是第1场得分23,所以James[4]是第4场得分31。第3行Love列表观念相同。
6-1-11 删除列表元素
可以使用下列方式删除指定索引的列表元素:
del name_list[i] # 删除索引i的列表元素
下列是删除列表区间元素。
del name_list[start:end] # 删除从索引start到(end-1)索引的列表元素
下列是删除区间,但是用step作为每隔多少区间再删除。
del name_list[start:end:step] # 每隔step,删除从索引start到(end-1)
索引的列表元素
程序实例ch6_14.py: 如果NBA勇士队主将阵容有5名,其中一名队员Bell离队了,可用下列方式设计。
# ch6_14.py
warriors = ['Curry', 'Durant', 'Iquodala', 'Bell', 'Thompson']
print("2018年初NBA勇士队主将阵容", warriors)
del warriors[3] # 不明原因离队
print("2018年末NBA勇士队主将阵容", warriors)
执行结果
2018年初NBA勇士队主将阵容 ['Curry', 'Durant', 'Iquodala', 'Bell', 'Thompson']
2018年末NBA勇士队主将阵容 ['Curry', 'Durant', 'Iquodala', 'Thompson']
程序实例ch6_15.py: 删除列表元素的应用。
# ch6_15.py
nums1 = [1, 3, 5]
print("删除nums1列表索引1元素前 = ",nums1)
del nums1[1]
print("删除nums1列表索引1元素后 = ",nums1)
nums2 = [1, 2, 3, 4, 5, 6]
print("删除nums2列表索引[0:2]前 = ",nums2)
del nums2[0:2]
print("删除nums2列表索引[0:2]后 = ",nums2)
nums3 = [1, 2, 3, 4, 5, 6]
print("删除nums3列表索引[0:6:2]前 = ",nums3)
del nums3[0:6:2]
print("删除nums3列表索引[0:6:2]后 = ",nums3)
执行结果
删除nums1列表索引1元素前 = [1, 3, 5]
删除nums1列表索引1元素后 = [1, 5]
删除nums2列表索引[0:2]前 = [1, 2, 3, 4, 5, 6]
删除nums2列表索引[0:2]后 = [3, 4, 5, 6]
删除nums3列表索引[0:6:2]前 = [1, 2, 3, 4, 5, 6]
删除nums3列表索引[0:6:2]后 = [2, 4, 6]
以这种方式删除列表元素最大的缺点是,元素删除后我们无法得知删除的是什么内容。有时我们设计网站时,可能想将某个人从VIP客户降为一般客户,采用上述方式删除元素时,我们就无法再度取得所删除的元素数据,未来笔者会介绍另一种方式删除数据,删除后我们还可善加利用所删除的数据。又或者你设计一个游戏,敌人是放在列表内,采用上述方式删除所杀死的敌人时,我们就无法再度取得所删除的敌人元素数据,如果我们可以取得的话,可以在杀死敌人坐标位置放置庆祝动画等。
6-1-12 列表为空列表的判断
如果想建立一个列表,可是暂时不放置元素,可使用下列方式定义。
name_list = [ ] # 这是空的列表
程序实例ch6_16.py: 删除列表元素的应用,这个程序基本上会用len( )函数判断列表内是否有元素数据,如果有则删除索引为0的元素,如果没有则列出列表内没有元素了。
# ch6_16.py
cars = ['Toyota', 'Nissan', 'Honda']
print("cars列表长度是 = %d" % len(cars))
if len(cars) != 0:
del cars[0]
print("删除cars列表元素成功")
print("cars列表长度是 = %d" % len(cars))
else:
print("cars列表内没有元素数据")
nums = []
print("nums列表长度是 = %d" % len(nums))
if len(nums) != 0:
del nums[0]
print("删除nums列表元素成功")
else:
print("nums列表内没有元素数据")
执行结果
cars列表长度是 = 3
删除cars列表元素成功
cars列表长度是 = 2
nums列表长度是 = 0
nums列表内没有元素数据
6-1-13 删除列表
Python也允许我们删除整个列表,列表一经删除后就无法复原,同时也无法做任何操作了,下列是删除列表的方式:
del name_list # 删除列表name_list
实例1: 建立列表、打印列表、删除列表,然后尝试再度打印列表结果出现错误信息,因为列表经删除后已经不存在了。
6-2 Python简单的面向对象观念
在面向对象的程序设计(Object Oriented Programming)观念里,所有数据皆算是一个对象(Object),例如,整数、浮点数、字符串或是本章所提的列表皆是一个对象。我们可以为所建立的对象设计一些方法(method),供这些对象使用,在这里所提的方法就是函数,其实方法与函数还是有一些差异,后面还会解说。目前Python有为一些基本对象提供默认的方法,要使用这些方法可以在对象后先放小数点,再放方法名称,基本语法格式如下:
对象.方法( )
下列将分成几个小节一步一步以实例说明。
6-2-1 字符串的方法
几个字符串操作常用的方法(method)如下:
- lower( ):将字符串转成小写字。
- upper( ):将字符串转成大写字。
- title( ):将字符串转成第一个字母大写,其他是小写。
- rstrip( ):删除字符串尾端多余的空白。
- lstrip( ):删除字符串开始端多余的空白。
- strip( ):删除字符串头尾两边多余的空白。
程序实例ch6_17.py: 将字符串改成小写,与将字符串改成大写,以及将字符串改成第一个字母大写,其他小写。
# ch6_17.py
strN = "DeepStone"
strU = strN.upper( ) # 改成大写
strL = strN.lower( ) # 改成小写
strT = strN.title( ) # 改成第一个字母大写其他小写
print("大写输出:",strU,"\n小写输出:",strL,"\n第一字母大写:",strT)
执行结果
大写输出: DEEPSTONE
小写输出: deepstone
第一字母大写: Deepstone
删除字符串开始或结尾多余空白是一个很好用的方法(method),特别是系统要求读者输入数据时,一定会有人不小心多输入了一些空格符,此时可以用这个方法删除多余的空白。
程序实例ch6_18.py: 删除开始端与结尾端多余空白的应用。
# ch6_18.py
strN = " DeepStone "
strL = strN.lstrip( ) # 删除字符串左边多余空白
strR = strN.rstrip( ) # 删除字符串右边多余空白
strB = strN.lstrip( ) # 先删除字符串左边多余空白
strB = strB.rstrip( ) # 再删除字符串右边多余空白
strO = strN.strip( ) # 一次删除头尾端多余空白
print("/%s/" % strN)
print("/%s/" % strL)
print("/%s/" % strR)
print("/%s/" % strB)
print("/%s/" % strO)
执行结果
/ DeepStone /
/DeepStone /
/ DeepStone/
/DeepStone/
/DeepStone/
6-2-2 更改字符串大小写
如果列表内的元素字符串数据是小写,例如:输出的车辆名称是“benz”,其实我们可以使用前一小节的title( )让开头车辆名称的第一个字母大写,可能会更好。
程序实例ch6_19.py: 将upper( )和title( )应用在字符串。
# ch6_19.py
cars = ['bmw', 'benz', 'audi']
carF = "我开的第一部车是 " + cars[1].title( )
carN = "我现在开的车子是 " + cars[0].upper( )
print(carF)
print(carN)
上述第4行是将bmw改为BMW。
执行结果
我开的第一部车是 Benz
我现在开的车子是 BMW
6-2-3 dir( )获得系统内部对象的方法
6-2-1节笔者列举了字符串常用的方法(method),dir( )函数可以列出对象有哪些内置的方法可以使用。
实例1: 列出字符串对象的方法,处理方式是可以先设定一个字符串变量,再列出此字符串变量的方法(method)。
上述圈起来的,笔者在6-2-1节已有解说。看到上述密密麻麻的方法,不用紧张,也不用想要一次学会,需要时再学即可。如果想要了解上述特定方法可以使用4-1节所介绍的help( )函数,可以用下列方式:
help(对象.方法名称)
实例2: 延续前一个实例,列出对象string,内置的islower的使用说明,同时以string对象为例,测试使用结果。
由上述说明可知,islower( )可以传回对象是否是小写,如果对象全部是小写或至少有一个字符是小写将传回True,否则传回False。在上述实例,由于string对象的内容是“abc”,全部是小写,所以传回True。
上述观念同样可以应用在查询整数对象的方法。
实例3: 列出整数对象的方法,同样可以先设定一个整数变量,再列出此整数变量的方法(method)。
上述bit_length是可以计算出要多少位以2进位方式存储此变量。
实例4: 列出需要多少位,存储实例3的整数变量num。
6-3 获得列表的方法
这节重点是列表,我们可以使用下列方式获得列表的方法。
实例1: 列出内置列表(list)内字符串(string)元素的方法。
上述实例的重点是我们先建立一个列表string,然后由此列表利用dir( )函数可以了解有哪些列表的方法可以使用。
实例2: 列出内置列表(list)内整数(int)元素的方法。
可以看到实例1与实例2内容完全相同,这表示下一节起讲解操作列表的方法,可以用在字符串元素,也可以用在整数元素。
6-4 增加与删除列表元素
6-4-1 在列表末端增加元素append( )
程序设计时常常会发生需要增加列表元素的情况,如果目前元素个数是3个,想要增加第4个元素,读者可能会想可否使用下列传统方式,直接设定新增的值:
name_list[3] = value
实例1: 使用索引方式,为列表增加元素,但是发生索引值超过列表长度的错误。
读者可能会想可以增加一个新列表,将欲新增的元素放在新列表,然后再将原先列表与新列表相加,就达到增加列表元素的目的了。这个方法理论是可以,可是太麻烦了。Python为列表内置了新增元素的方法append( ),这个方法,可以在列表末端直接增加元素。
name_list.append(‘新增元素')
程序实例ch6_20.py: 先建立一个空列表,然后分别使用append( )增加3个元素内容。
# ch6_20.py
cars = []
print("目前列表内容 = ",cars)
cars.append('Honda')
print("目前列表内容 = ",cars)
cars.append('Toyota')
print("目前列表内容 = ",cars)
cars.append('Ford')
print("目前列表内容 = ",cars)
执行结果
目前列表内容 = []
目前列表内容 = ['Honda']
目前列表内容 = ['Honda', 'Toyota']
目前列表内容 = ['Honda', 'Toyota', 'Ford']
6-4-2 插入列表元素insert( )
append( )方法是固定在列表末端插入元素,insert( )方法则是可以在任意位置插入元素,它的使用格式如下:
insert(索引, 元素内容) # 索引是插入位置,元素内容是插入内容
程序实例ch6_21.py: 使用insert( )插入列表元素的应用。
# ch6_21.py
cars = ['Honda','Toyota','Ford']
print("目前列表内容 = ",cars)
print("在索引1位置插入Nissan")
cars.insert(1,'Nissan')
print("新的列表内容 = ",cars)
print("在索引0位置插入BMW")
cars.insert(0,'BMW')
print("最新列表内容 = ",cars)
执行结果
目前列表内容 = ['Honda', 'Toyota', 'Ford']
在索引1位置插入Nissan
新的列表内容 = ['Honda', 'Nissan', 'Toyota', 'Ford']
在索引0位置插入BMW
最新列表内容 = ['BMW', 'Honda', 'Nissan', 'Toyota', 'Ford']
6-4-3 删除列表元素pop( )
6-1-8节笔者有介绍使用del删除列表元素,在该节笔者同时指出最大缺点是,资料删除了就无法取得相关信息。使用pop( )方法删除元素最大的优点是,删除后将弹出所删除的值,使用pop( )时若是未指明所删除元素的位置,一律删除列表末端的元素。pop( )的使用方式如下:
value = name_list.pop( ) # 没有索引是删除列表末端元素
value = name_list.pop(i) # 是删除指定索引值的列表元素
程序实例ch6_22.py: 使用pop( )删除列表元素的应用,这个程序第5行未指明删除的索引值,所以删除了列表的最后一个元素。程序第9行则是指明删除索引值为1的元素。
# ch6_22.py
cars = ['Honda','Toyota','Ford','BMW']
print("目前列表内容 = ",cars)
print("使用pop( )删除列表元素")
popped_car = cars.pop( ) # 删除列表末端值
print("所删除的列表内容是 : ", popped_car)
print("新的列表内容 = ",cars)
print("使用pop(1)删除列表元素")
popped_car = cars.pop(1) # 删除列表索引为1的值
print("所删除的列表内容是 : ", popped_car)
print("新的列表内容 = ",cars)
执行结果
目前列表内容 = ['Honda', 'Toyota', 'Ford', 'BMW']
使用pop( )删除列表元素
所删除的列表内容是 : BMW
新的列表内容 = ['Honda', 'Toyota', 'Ford']
使用pop(1)删除列表元素
所删除的列表内容是 : Toyota
新的列表内容 = ['Honda', 'Ford']
6-4-4 删除指定的元素remove( )
在删除列表元素时,有时可能不知道元素在列表内的位置,此时可以使用remove( )方法删除指定的元素,它的使用方式如下:
name_list.remove(想删除的元素内容)
如果列表内有相同的元素,则只删除第一个出现的元素,如果想要删除所有相同的元素,必须使用循环,下一章将会讲解循环的观念。
程序实例ch6_23.py: 删除列表中第一次出现的元素bmw,这个列表有2个bmw字符串,最后只删除索引为1的bmw字符串。
# ch6_23.py
cars = ['Honda','bmw','Toyota','Ford','bmw']
print("目前列表内容 = ",cars)
print("使用remove( )删除列表元素")
expensive = 'bmw'
cars.remove(expensive) # 删除第一次出现的元素bmw
print("所删除的内容是: " + expensive.upper( ) + " 因为太贵了" )
print("新的列表内容",cars)
执行结果
目前列表内容 = ['Honda', 'bmw', 'Toyota', 'Ford', 'bmw']
使用remove( )删除列表元素
所删除的内容是: BMW 因为太贵了
新的列表内容 ['Honda', 'Toyota', 'Ford', 'bmw']
6-5 列表的排序
6-5-1 颠倒排序reverse( )
reverse( )可以颠倒排序列表元素,它的使用方式如下:
name_list.reverse( ) # 颠倒排序name_list列表元素
其实在6-1-3节的切片应用中,也可以用[::-1]方式取得列表颠倒排序。
程序实例ch6_24.py: 使用2种方式执行颠倒排序列表元素。
# ch6_24.py
cars = ['Honda','bmw','Toyota','Ford','bmw']
print("目前列表内容 = ",cars)
# 直接打印cars[::-1]颠倒排序,不更改列表内容
print("打印使用[::-1]颠倒排序\n", cars[::-1])
# 更改列表内容
print("使用reverse( )颠倒排序列表元素")
cars.reverse( ) # 颠倒排序列表
print("新的列表内容 = ",cars)
执行结果
目前列表内容 = ['Honda', 'bmw', 'Toyota', 'Ford', 'bmw']
打印使用[::-1]颠倒排序
['bmw', 'Ford', 'Toyota', 'bmw', 'Honda']
使用reverse( )颠倒排序列表元素
新的列表内容 = ['bmw', 'Ford', 'Toyota', 'bmw', 'Honda']
列表经颠倒排放后,就算永久性更改了,如果要复原,可以再执行一次reverse( )方法。
6-5-2 sort( )排序
sort( )方法可以对列表元素由小到大排序,这个方法同时对纯数值元素与纯英文字符串元素有非常好的效果。需要注意的是,经排序后原列表的元素顺序会被永久更改。它的使用格式如下:
name_list.sort( ) # 由小到大排序name_list列表
如果是排序英文字符串,建议先将字符串英文字符全部改成小写或全部改成大写。
程序实例ch6_25.py: 数字与英文字符串元素排序的应用。
# ch6_25.py
cars = ['honda','bmw','toyota','ford']
print("目前列表内容 = ",cars)
print("使用sort( )由小排到大")
cars.sort( )
print("排序列表结果 = ",cars)
nums = [5, 3, 9, 2]
print("目前列表内容 = ",nums)
print("使用sort( )由小排到大")
nums.sort( )
print("排序列表结果 = ",nums)
执行结果
目前列表内容 = ['honda', 'bmw', 'toyota', 'ford']
使用sort( )由小排到大
排序列表结果 = ['bmw', 'ford', 'honda', 'toyota']
目前列表内容 = [5, 3, 9, 2]
使用sort( )由小排到大
排序列表结果 = [2, 3, 5, 9]
上述内容是由小排到大,sort( )方法是允许由大排到小,只要在sort( )内增加参数“reverse=True”即可。
程序实例ch6_26.py: 重新设计ch6_25.py,将列表元素由大排到小。
# ch6_26.py
cars = ['honda','bmw','toyota','ford']
print("目前列表内容 = ",cars)
print("使用sort( )由大排到小")
cars.sort(reverse=True)
print("排序列表结果 = ",cars)
nums = [5, 3, 9, 2]
print("目前列表内容 = ",nums)
print("使用sort( )由大排到小")
nums.sort(reverse=True)
print("排序列表结果 = ",nums)
执行结果
目前列表内容 = ['honda', 'bmw', 'toyota', 'ford']
使用sort( )由大排到小
排序列表结果 = ['toyota', 'honda', 'ford', 'bmw']
目前列表内容 = [5, 3, 9, 2]
使用sort( )由大排到小
排序列表结果 = [9, 5, 3, 2]
6-5-3 sorted( )排序
前一小节的sort( )排序将造成列表元素顺序永久更改,如果你不希望更改列表元素顺序,可以使用另一种排序sorted( ),使用这个排序可以获得想要的排序结果,我们可以用新列表存储新的排序列表,同时原先列表的顺序将不更改。它的使用格式如下:
new_list.sorted(name_list) # 用新列表存储排序,原列表序列不更改
程序实例ch6_27.py: sorted( )排序的应用,这个程序使用car_sorted新列表存储car列表的排序结果,同时使用num_sorted新列表存储num列表的排序结果。
# ch6_27.py
cars = ['honda','bmw','toyota','ford']
print("目前列表car内容 = ",cars)
print("使用sorted( )由小排到大")
cars_sorted = sorted(cars)
print("排序列表结果 = ",cars_sorted)
print("原先列表car内容 = ",cars)
nums = [5, 3, 9, 2]
print("目前列表num内容 = ",nums)
print("使用sorted( )由小排到大")
nums_sorted = sorted(nums)
print("排序列表结果 = ",nums_sorted)
print("原先列表num内容 = ",nums)
执行结果
目前列表car内容 = ['honda', 'bmw', 'toyota', 'ford']
使用sorted( )由小排到大
排序列表结果 = ['bmw', 'ford', 'honda', 'toyota']
原先列表car内容 = ['honda', 'bmw', 'toyota', 'ford']
目前列表num内容 = [5, 3, 9, 2]
使用sorted( )由小排到大
排序列表结果 = [2, 3, 5, 9]
原先列表num内容 = [5, 3, 9, 2]
如果我们想要从大排到小,可以在sorted( )内增加参数“reverse=True”,可参考下列实例第5和11行。
程序实例ch6_28.py: 重新设计ch6_27.py,将列表由大排到小。
# ch6_28.py
cars = ['honda','bmw','toyota','ford']
print("目前列表car内容 = ",cars)
print("使用sorted( )由大排到小")
cars_sorted = sorted(cars,reverse=True)
print("排序列表结果 = ",cars_sorted)
print("原先列表car内容 = ",cars)
nums = [5, 3, 9, 2]
print("目前列表num内容 = ",nums)
print("使用sorted( )由大排到小")
nums_sorted = sorted(nums,reverse=True)
print("排序列表结果 = ",nums_sorted)
print("原先列表num内容 = ",nums)
执行结果
目前列表car内容 = ['honda', 'bmw', 'toyota', 'ford']
使用sorted( )由大排到小
排序列表结果 = ['toyota', 'honda', 'ford', 'bmw']
原先列表car内容 = ['honda', 'bmw', 'toyota', 'ford']
目前列表num内容 = [5, 3, 9, 2]
使用sorted( )由大排到小
排序列表结果 = [9, 5, 3, 2]
原先列表num内容 = [5, 3, 9, 2]
6-6 进阶列表操作
6-6-1 index( )
这个方法可以返回特定元素内容第一次出现的索引值,它的使用格式如下:
索引值 = 列表名称.index(搜寻值)
如果搜寻值不在列表会出现错误。
程序实例ch6_29.py:返回搜寻索引值的应用。
# ch6_29.py
cars = ['toyota', 'nissan', 'honda']
search_str = 'nissan'
i = cars.index(search_str)
print("所搜寻元素 %s 第一次出现位置索引是 %d" % (search_str, i))
nums = [7, 12, 30, 12, 30, 9, 8]
search_val = 30
j = nums.index(search_val)
print("所搜寻元素 %s 第一次出现位置索引是 %d" % (search_val, j))
执行结果
所搜寻元素 nissan 第一次出现位置索引是 1
所搜寻元素 30 第一次出现位置索引是 2
程序实例ch6_30.py: 使用ch6_13.py的列表James,这个列表有Lebron James一系列比赛得分,由此列表请计算他在第几场得最高分,同时列出所得分数。
# ch6_30.py
James = ['Lebron James',23, 19, 22, 31, 18] # 定义James列表
games = len(James) # 求元素数量
score_Max = max(James[1:games]) # 最高得分
i = James.index(score_Max) # 场次
print(James[0], "在第 %d 场得最高分 %d" % (i, score_Max))
执行结果
Lebron James 在第 4 场得最高分 31
这个实例有一点不完美,因为如果有2场或更多场次得到相同分数的最高分,本程序无法处理,下一章笔者将以实例讲解如何修订此缺点。
6-6-2 count( )
这个方法可以返回特定元素内容出现的次数,它的使用格式如下:
次数 = 列表名称.count(搜寻值)
如果搜寻值不在列表会出现错误。
程序实例ch6_31.py: 返回搜寻值出现的次数的应用。
# ch6_31_1.py
char = '-'
lst = ['Silicon', 'Stone', 'Education']
print(char.join(lst))
char ='***'
lst = ['Silicon', 'Stone', 'Education']
print(char.join(lst))
char = '\n' # 换行字符
lst = ['Silicon', 'Stone', 'Education']
print(char.join(lst))
执行结果
Silicon-Stone-Education
Silicon***Stone***Education
Silicon
Stone
Education
6-6-3 列表元素的组合join( )
这个方法可以将列表的元素组成一个字符串,它的使用格式如下:
char.join(seq) # seq表示参数必须是列表、元组等序列数据
至于char则是组合后各元素间的分隔字符,可以是单一字符,也可以是字符串。
程序实例ch6_31_1.py: 列表元素组合的应用。
# ch6_31.py
cars = ['toyota', 'nissan', 'honda']
search_str = 'nissan'
num1 = cars.count(search_str)
print("所搜寻元素 %s 出现 %d 次" % (search_str, num1))
nums = [7, 12, 30, 12, 30, 9, 8]
search_val = 30
num2 = nums.count(search_val)
print("所搜寻元素 %s 出现 %d 次" % (search_val, num2))
执行结果
所搜寻元素 nissan 出现 1 次
所搜寻元素 30 出现 2 次
6-7 列表内含列表
列表内含列表的基本格式如下:
num = [1, 2, 3, 4, 5, [6, 7, 8]]
对上述而言,num是一个列表,在这个列表内有另一个列表[7, 8, 9],因为内部列表的索引值是5,所以可以用num[5],获得这个元素列表的内容。
如果想要存取列表内的列表元素,可以使用下列格式:
num[索引1][索引2]
索引1是元素列表原先索引位置,索引2是元素列表内部的索引。
实例1: 列出列表内的列表元素值。
列表内含列表主要应用是,例如,可以用这个资料格式存储NBA球员Lebron James的数据如下所示:
James = [[‘Lebron James', ‘SF','12/30/1984'], 23, 19, 22, 31, 18]
其中第一个元素是列表,用于存储Lebron James个人资料,其他则是存储每场得分数据。
程序实例ch6_32.py: 扩充ch6_30.py;先列出Lebron James个人资料;再计算哪一个场次得到最高分。程序第2行,SF全名是Small Forward(小前锋)。
# ch6_32.py
James = [['Lebron James','SF','12/30/84'],23,19,22,31,18] # 定义James列表
games = len(James) # 求元素数量
score_Max = max(James[1:games]) # 最高得分
i = James.index(score_Max) # 场次
name = James[0][0]
position = James[0][1]
born = James[0][2]
print("姓名 : ", name)
print("位置 : ", position)
print("出生日期 : ", born)
print("在第 %d 场得最高分 %d" % (i, score_Max))
执行结果
姓名 : Lebron James
位置 : SF
出生日期 : 12/30/84
在第 4 场得最高分 31
6-7-1 再谈append( )
在6-4-1节我们有提过可以使用append( )方法,将元素插入列表的末端,其实也可以使用append( )函数将某一列表插入另一列表的末端,方法与插入元素方式相同,这时就会产生列表中有列表的效果。它的使用格式如下:
列表A.append(列表B) # 列表B将接在列表A末端
程序实例ch6_33.py: 使用append( )将列表插入另一列表的末端。
# ch6_33.py
cars1 = ['toyota', 'nissan', 'honda']
cars2 = ['ford', 'audi']
print("原先cars1列表内容 = ", cars1)
print("原先cars2列表内容 = ", cars2)
cars1.append(cars2)
print("执行append( )后列表cars1内容 = ", cars1)
print("执行append( )后列表cars2内容 = ", cars2)
执行结果
原先cars1列表内容 = ['toyota', 'nissan', 'honda']
原先cars2列表内容 = ['ford', 'audi']
执行append( )后列表cars1内容 = ['toyota', 'nissan', 'honda', ['ford', 'audi']]
执行append( )后列表cars2内容 = ['ford', 'audi']
6-7-2 extend( )
这也是2个列表连接的方法,与append( )类似,不过这个方法只适用2个列表连接,不能用在一般元素。同时在连接后,extend( )会将列表分解成元素,一一插入列表。它的使用格式如下:
列表A.extend(列表B) # 列表B将分解成元素插入列表A末端
程序实例ch6_34.py:使用extend( )方法取代ch6_32.py,并观察执行结果。
# ch6_34.py
cars1 = ['toyota', 'nissan', 'honda']
cars2 = ['ford', 'audi']
print("原先cars1列表内容 = ", cars1)
print("原先cars2列表内容 = ", cars2)
cars1.extend(cars2)
print("执行extend( )后列表cars1内容 = ", cars1)
print("执行extend( )后列表cars2内容 = ", cars2)
执行结果
原先cars1列表内容 = ['toyota', 'nissan', 'honda']
原先cars2列表内容 = ['ford', 'audi']
执行extend( )后列表cars1内容 = ['toyota', 'nissan', 'honda', 'ford', 'audi']
执行extend( )后列表cars2内容 = ['ford', 'audi']
上述执行后cars1将是含有5个元素的列表,每个元素皆是字符串。
6-8 列表的复制
6-8-1 列表的深复制-deep copy
假设我喜欢的运动是,篮球与棒球,可以用下列方式设定列表:
mysports = ['basketball','baseball']
如果我的朋友也喜欢这2种运动,读者可能会想用下列方式设定列表。
friendsports = mysports
程序实例ch6_35.py:列出我和朋友所喜欢的运动。
# ch6_35.py
mysports = ['basketball', 'baseball']
friendsports = mysports
print("我喜欢的运动 = ", mysports)
print("我朋友喜欢的运动 = ", friendsports)
执行结果
我喜欢的运动 = ['basketball', 'baseball']
我朋友喜欢的运动 = ['basketball', 'baseball']
初看上述执行结果好像没有任何问题,可是如果我想加入football(美式足球)当作喜欢的运动,我的朋友想加入soccer(传统足球)当作喜欢的运动,这时我喜欢的运动如下:
basketball、baseball、football
我朋友喜欢的运动如下:
basketball、baseball、soccer
程序实例ch6_36.py:继续使用ch6_35.py,加入football(美式足球)当作喜欢的运动,我的朋友想加入soccer(传统足球)当作喜欢的运动,同时列出执行结果。
# ch6_36.py
mysports = ['basketball', 'baseball']
friendsports = mysports
print("我喜欢的运动 = ", mysports)
print("我朋友喜欢的运动 = ", friendsports)
mysports.append('football')
friendsports.append('soccer')
print("我喜欢的最新运动 = ", mysports)
print("我朋友喜欢的最新运动 = ", friendsports)
执行结果
我喜欢的运动 = ['basketball', 'baseball']
我朋友喜欢的运动 = ['basketball', 'baseball']
我喜欢的最新运动 = ['basketball', 'baseball', 'football', 'soccer']
我朋友喜欢的最新运动 = ['basketball', 'baseball', 'football', 'soccer']
这时获得的结果,不论是我还是我的朋友,喜欢的运动皆相同,football和soccer皆是变成2人共同喜欢的运动。类似这种只要有一个列表更改元素会影响到另一个列表同步更改的复制称深复制(deep copy)。
6-8-2 地址的观念
使用Python可以使用id( )函数,获得变量的地址,可参考下列语法。
id(x)
上述可以获得变量x的地址。对于列表而言,如果使用下列方式设定2个列表变量相等,相当于只是将变量地址复制给另一个变量。
friendsports = mysports
上述相当于是将mysports变量地址复制给friendsports。所以程序实例ch6_36.py在执行时,2个列表变量所指的地址相同,所以新增运动项目时,皆是将运动项目加在同一变量地址,可参考下列实例。
程序实例ch6_37.py:重新设计ch6_36.py,增加列出列表变量的地址。
# ch6_37.py
mysports = ['basketball', 'baseball']
friendsports = mysports
print("列出mysports地址 = ", id(mysports))
print("列出friendsports地址 = ", id(friendsports))
print("我喜欢的运动 = ", mysports)
print("我朋友喜欢的运动 = ", friendsports)
mysports.append('football')
friendsports.append('soccer')
print(" -- 新增运动项目后 -- ")
print("列出mysports地址 = ", id(mysports))
print("列出friendsports地址 = ", id(friendsports))
print("我喜欢的最新运动 = ", mysports)
print("我朋友喜欢的最新运动 = ", friendsports)
执行结果
列出mysports地址 = 2742575138176
列出friendsports地址 = 2742575138176
我喜欢的运动 = ['basketball', 'baseball']
我朋友喜欢的运动 = ['basketball', 'baseball']
-- 新增运动项目后 --
列出mysports地址 = 2742575138176
列出friendsports地址 = 2742575138176
我喜欢的最新运动 = ['basketball', 'baseball', 'football', 'soccer']
我朋友喜欢的最新运动 = ['basketball', 'baseball', 'football', 'soccer']
由上述执行结果可以看到,使用程序第3行设定列表变量相等时,实际只是将列表地址复制给另一个列表变量。
6-8-3 列表的浅复制-shallow copy
浅复制(shallow copy)观念是,执行复制后当一个列表改变后,不会影响另一个列表的内容,这是本小节的重点。方法应该如下:
friendsports = mysports[ : ]
程序实例ch6_38.py:使用浅复制方式,重新设计ch6_36.py。下列是与ch6_36.py之间,唯一不同的程序代码。
# ch6_38.py
mysports = ['basketball', 'baseball']
friendsports = mysports[:]
print("列出mysports地址 = ", id(mysports))
print("列出friendsports地址 = ", id(friendsports))
print("我喜欢的运动 = ", mysports)
print("我朋友喜欢的运动 = ", friendsports)
mysports.append('football')
friendsports.append('soccer')
print(" -- 新增运动项目后 -- ")
print("列出mysports地址 = ", id(mysports))
print("列出friendsports地址 = ", id(friendsports))
print("我喜欢的最新运动 = ", mysports)
print("我朋友喜欢的最新运动 = ", friendsports)
执行结果
列出mysports地址 = 2134571451776
列出friendsports地址 = 2134572299136
我喜欢的运动 = ['basketball', 'baseball']
我朋友喜欢的运动 = ['basketball', 'baseball']
-- 新增运动项目后 --
列出mysports地址 = 2134571451776
列出friendsports地址 = 2134572299136
我喜欢的最新运动 = ['basketball', 'baseball', 'football']
我朋友喜欢的最新运动 = ['basketball', 'baseball', 'soccer']
由上述执行结果可知,我们已经获得了2个列表彼此是不同的列表地址,同时也得到了想要的结果。
6-9 再谈字符串
3-4节笔者介绍了字符串(string)的观念,在Python的应用中可以将单一字符串当作是一个序列,这个序列是由字符(character)所组成,可想成字符序列。不过字符串与列表不同的是,字符串内的单一元素内容是不可更改的。
6-9-1 字符串的索引
可以使用索引值的方式取得字符串内容,索引方式则与列表相同。
程序实例ch6_39.py:使用正值与负值的索引列出字符串元素内容。
# ch6_39.py
string = "Python"
# 正值索引
print(" string[0] = ", string[0],
"\n string[1] = ", string[1],
"\n string[2] = ", string[2],
"\n string[3] = ", string[3],
"\n string[4] = ", string[4],
"\n string[5] = ", string[5])
# 负值索引
print(" string[-1] = ", string[-1],
"\n string[-2] = ", string[-2],
"\n string[-3] = ", string[-3],
"\n string[-4] = ", string[-4],
"\n string[-5] = ", string[-5],
"\n string[-6] = ", string[-6])
# 多重指定观念
s1, s2, s3, s4, s5, s6 = string
print("多重指定观念的输出测试 = ",s1,s2,s3,s4,s5,s6)
执行结果
string[0] = P
string[1] = y
string[2] = t
string[3] = h
string[4] = o
string[5] = n
string[-1] = n
string[-2] = o
string[-3] = h
string[-4] = t
string[-5] = y
string[-6] = P
多重指定观念的输出测试 = P y t h o n
6-9-2 字符串切片
6-1-3节列表切片的观念可以应用在字符串,下列将直接以实例说明。
程序实例ch6_40.py:字符串切片的应用。
# ch6_40.py
string = "Deep Learning" # 定义字符串
print("打印string第1-3元素 = ", string[0:3])
print("打印string第2-4元素 = ", string[1:4])
print("打印string第2,4,6元素 = ", string[1:6:2])
print("打印string第1到最后元素 = ", string[1:])
print("打印string前3元素 = ", string[0:3])
print("打印string后3元素 = ", string[-3:])
6-9-3 函数或方法
除了会更改内容的列表函数或方法不可应用在字符串外,其他则可以用在字符串。
程序实例ch6_41.py:将函数len( )、max( )、min( )应用在字符串。
# ch6_41.py
string = "Deep Learning" # 定义字符串
strlen = len(string)
print("字符串长度", strlen)
maxstr = max(string)
print("字符串最大的unicode码值和字符", ord(maxstr), maxstr)
minstr = min(string)
print("字符串最小的unicode码值和字符", ord(minstr), minstr)
执行结果
字符串长度 13
字符串最大的unicode码值和字符 114 r
字符串最小的unicode码值和字符 32
6-9-4 将字符串转成列表
list( )函数可以将参数内的对象转成列表,下列是字符串转为列表的实例:
6-9-5 切片赋值的应用
字符串本身无法用切片方式更改内容,但是将字符串改为列表后,就可以使用切片更改列表内容了,下列是延续6-9-4节的实例。
6-9-6 使用split( )处理字符串
这个方法(method),可以将字符串以空格为分隔符,将字符串拆开,变成一个列表。变成列表后我们可以使用len( )获得此列表的元素个数,这相当于可以计算字符串是由多少个英文字母组成,由于中文字之间没有空格,所以本节所述方法只适用在纯英文文件。如果我们可以将一篇文章或一本书当做一个字符串变量,可以使用这个方法获得这一篇文章或这一本书的字数。
程序实例ch6_41_1.py:获得字符串内的字数。
# ch6_41_1.py
str1 = "Silicon Stone Education"
str2 = "DeepStone"
str3 = "深石数位"
sList1 = str1.split() # 字符串转成列表
sList2 = str2.split() # 字符串转成列表
sList3 = str3.split() # 字符串转成列表
print(str1, " 列表内容是 ", sList1) # 打印列表
print(str1, " 列表字数是 ", len(sList1)) # 打印字数
print(str2, " 列表内容是 ", sList2) # 打印列表
print(str2, " 列表字数是 ", len(sList2)) # 打印字数
print(str3, " 列表内容是 ", sList3) # 打印列表
print(str3, " 列表字数是 ", len(sList3)) # 打印字数
执行结果
Silicon Stone Education 列表内容是 ['Silicon', 'Stone', 'Education']
Silicon Stone Education 列表字数是 3
DeepStone 列表内容是 ['DeepStone']
DeepStone 列表字数是 1
深石数位 列表内容是 ['深石数位']
深石数位 列表字数是 1
6-10 in和not in表达式
主要是用于判断一个对象是否属于另一个对象,对象可以是字符串(string)、列表(list)、元组(Tuple) (第8章介绍)、字典(Dict) (第9章介绍)。它的语法格式如下:
boolean_value = obj1 in obj2 # 对象obj1在对象obj2内会传回True boolean_value = obj1 not in obj2 # 对象obj1不在对象obj2内会传回True
程序实例ch6_42.py:请输入字符,这个程序会判断字符是否在字符串内。
# ch6_42.py
password = 'deepstone'
ch = input("请输入字符 = ")
print("in表达式")
if ch in password:
print("输入字符在密码中")
else:
print("输入字符不在密码中")
print("not in表达式")
if ch not in password:
print("输入字符不在密码中")
else:
print("输入字符在密码中")
执行结果
Silicon Stone Education 列表内容是 ['Silicon', 'Stone', 'Education']
Silicon Stone Education 列表字数是 3
DeepStone 列表内容是 ['DeepStone']
DeepStone 列表字数是 1
深石数位 列表内容是 ['深石数位']
深石数位 列表字数是 1
其实这个功能一般更常见是用在侦测某个元素是否存在列表中,如果不存在,则将它加入列表内,可参考下列实例。
程序实例ch6_43.py:这个程序基本上会要求输入一个水果,如果列表内目前没有这个水果,就将输入的水果加入列表内。
# ch6_43.py
fruits = ['apple', 'banana', 'watermelon']
fruit = input("请输入水果 = ")
if fruit in fruits:
print("这个水果已经有了")
else:
fruits.append(fruit)
print("谢谢提醒已经加入水果清单: ", fruits)
执行结果
in表达式
输入字符不在密码中
not in表达式
输入字符不在密码中
6-11 is或is not表达式
可以用于比较两个对象是否相同,在此所谓相同并不只是内容相同,而是指对象变量指向相同的内存,对象可以是变量、字符串、列表、元组(Tuple) (第8章介绍)、字典(Dict) (第9章介绍)。它的语法格式如下:
boolean_value = obj1 is obj2 # 对象obj1等于对象obj2会传回True boolean_value = obj1 is not obj2 # 对象obj1不等于对象obj2会传回True
6-11-1 整数变量在内存地址的观察
在6-8-2节已经讲解可以使用id( )函数获得列表变量地址,其实这个函数也可以获得整数(或浮点数)变量在内存中的地址,当我们在Python程序中设立变量时,如果两个整数(或浮点数)变量内容相同,它们会使用相同的内存地址存储此变量。
程序实例ch6_44.py:整数变量在内存地址的观察,这个程序比较特别的是,程序执行初,变量x和y值是10,所以可以看到经过id( )函数后,彼此有相同的内存位置。变量z和r由于值与x和y不相同,所以有不同的内存地址,经过第9行运算后r的值变为10,最后得到x、y和r不仅值相同,同时也指向相同的内存地址。
# ch6_44.py
x = 10
y = 10
z = 15
r = 20
print("x = %d, y = %d, z = %d, r = %d" % (x, y, z, r))
print("x地址 = %d, y地址 = %d, z地址 = %d, r地址 = %d"
% (id(x), id(y), id(z), id(r)))
r = z # r的值将变为10
print("x = %d, y = %d, z = %d, r = %d" % (x, y, z, r))
print("x地址 = %d, y地址 = %d, z地址 = %d, r地址 = %d"
% (id(x), id(y), id(z), id(r)))
执行结果
in表达式
输入字符不在密码中
not in表达式
输入字符不在密码中
PS E:\桌面Desktop\Python王者归来\代码\ch6> & D:/Python311/python.exe e:/桌面Desktop/Python王者归来/代码/ch6/ch6_44.py
x = 10, y = 10, z = 15, r = 20
x地址 = 140718828872776, y地址 = 140718828872776, z地址 = 140718828872936, r地址 = 140718828873096
x = 10, y = 10, z = 15, r = 15
x地址 = 140718828872776, y地址 = 140718828872776, z地址 = 140718828872936, r地址 = 140718828872936
当r变量值变为10时,它所指的内存地址与x和y变量相同了。
6-11-2 将is和is not表达式应用在整数变量
程序实例ch6_45.py:is和is not表达式应用在整数变量。
# ch6_45.py
x = 10
y = 10
z = 15
r = z - 5
boolean_value = x is y
print("x地址 = %d, y地址 = %d" % (id(x), id(y)))
print("x = %d, y = %d, " % (x, y), boolean_value)
boolean_value = x is z
print("x地址 = %d, z地址 = %d" % (id(x), id(z)))
print("x = %d, z = %d, " % (x, z), boolean_value)
boolean_value = x is r
print("x地址 = %d, r地址 = %d" % (id(x), id(r)))
print("x = %d, r = %d, " % (x, r), boolean_value)
boolean_value = x is not y
print("x地址 = %d, y地址 = %d" % (id(x), id(y)))
print("x = %d, y = %d, " % (x, y), boolean_value)
boolean_value = x is not z
print("x地址 = %d, z地址 = %d" % (id(x), id(z)))
print("x = %d, z = %d, " % (x, z), boolean_value)
boolean_value = x is not r
print("x地址 = %d, r地址 = %d" % (id(x), id(r)))
print("x = %d, r = %d, " % (x, r), boolean_value)
执行结果
x地址 = 140718828872776, y地址 = 140718828872776
x = 10, y = 10, True
x地址 = 140718828872776, z地址 = 140718828872936
x = 10, z = 15, False
x地址 = 140718828872776, r地址 = 140718828872776
x = 10, r = 10, True
x地址 = 140718828872776, y地址 = 140718828872776
x = 10, y = 10, False
x地址 = 140718828872776, z地址 = 140718828872936
x = 10, z = 15, True
x地址 = 140718828872776, r地址 = 140718828872776
x = 10, r = 10, False
6-11-3 将is和is not表达式应用在列表变量
程序实例ch6_46.py:这个范例所使用的3个列表内容均是相同,但是mysports和sports1所指地址相同所以会被视为相同对象,sports2则指向不同地址所以会被视为不同对象,在使用is指令测试时,不同地址的列表会被视为不同的列表。
# ch6_46.py
mysports = ['basketball', 'baseball']
sports1 = mysports # 拷贝地址
sports2 = mysports[:] # 拷贝新串行
print("我喜欢的运动 = ", mysports, "地址是 = ", id(mysports))
print("运动 1 = ", sports1, "地址是 = ", id(sports1))
print("运动 2 = ", sports2, "地址是 = ", id(sports2))
boolean_value = mysports is sports1
print("我喜欢的运动 is 运动 1 = ", boolean_value)
boolean_value = mysports is sports2
print("我喜欢的运动 is 运动 2 = ", boolean_value)
boolean_value = mysports is not sports1
print("我喜欢的运动 is not 运动 1 = ", boolean_value)
boolean_value = mysports is not sports2
print("我喜欢的运动 is not 运动 2 = ", boolean_value)
执行结果
我喜欢的运动 = ['basketball', 'baseball'] 地址是 = 2361001477504
运动 1 = ['basketball', 'baseball'] 地址是 = 2361001477504
运动 2 = ['basketball', 'baseball'] 地址是 = 2361002259328
我喜欢的运动 is 运动 1 = True
我喜欢的运动 is 运动 2 = False
我喜欢的运动 is not 运动 1 = False
我喜欢的运动 is not 运动 2 = True
6-12 enumerate对象
enumerate( )方法可以将iterable类数值的元素用计数值与元素配对方式传回,返回的数据称enumerate对象。其中iterable类数值可以是列表(list)、元组(tuple)(第8章说明)、集合(set) (第10章说明)等。它的语法格式如下: obj = enumerate(iterable[, start = 0]) # 如果省略start = 设定,默认值是0未来我们可以使用list( )将enumerate对象转成列表,使用tuple( )将enumerate对象转成元组(第8章说明)。
程序实例ch6_47.py:将列表数据转成enumerate对象的应用。
# ch6_47.py
drinks = {"coffee", "tea", "wine"}
enumerate_drinks = enumerate(drinks) # 数值初始是0
print(enumerate_drinks) # 传回enumerate对象所在内存
print("下列是输出enumerate对象类型")
print(type(enumerate_drinks)) # 列出对象类型
执行结果
<enumerate object at 0x00000233B292C9F0>
下列是输出enumerate对象类型
<class 'enumerate'>
程序实例ch6_48.py:将列表数据转成enumerate对象,再将enumerate对象转成列表的实例,start起始值分别为0和10。
# ch6_48.py
drinks = {"coffee", "tea", "wine"}
enumerate_drinks = enumerate(drinks) # 数值初始是0
print("转成列表输出, 初始值是 0 = ", list(enumerate_drinks))
enumerate_drinks = enumerate(drinks, start = 10) # 数值初始是10
print("转成列表输出, 初始值是10 = ", list(enumerate_drinks))
执行结果
转成列表输出, 初始值是 0 = [(0, 'coffee'), (1, 'tea'), (2, 'wine')]
转成列表输出, 初始值是10 = [(10, 'coffee'), (11, 'tea'), (12, 'wine')]
上述程序第4行的list( )函数可以将enumerate对象转成列表,在7-5节当笔者介绍完循环后,还将继续使用循环解析enumerate对象。
习题
1 请用列表同时用英文列出10个心中想去旅游的地方。
(A):列出这10个地方。
(B):反向列出这10个地方。
©:由小排到大,同时列出来。
(D):由大排到小,同时列出来。
(E):请在第一个位置增加“Antarctic ”,请在最后位置增加“Arctic Sea”。
(F):请在中央位置增加“Chicago”。
(G):请分别删除第3和9个元素。
2 请用中文重新设计上述程序。
3 请建立一个晚会宴客名单,有3份资料。请做一个选单,每次执行皆会列出目前邀请名单,同时有选单,如果选择1,可以增加一位邀请名单。如果选择2,可以删除一位邀请名单。以目前所学指令,执行程序一次只能调整一次,其他细节可以自行发挥创意。