Python程序设计基础教程课件 第06章 切片和推导式_第1页
Python程序设计基础教程课件 第06章 切片和推导式_第2页
Python程序设计基础教程课件 第06章 切片和推导式_第3页
Python程序设计基础教程课件 第06章 切片和推导式_第4页
Python程序设计基础教程课件 第06章 切片和推导式_第5页
已阅读5页,还剩51页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Python程序设计基础教程

第6章切片和推导式提纲切片概念用切片检索元素用切片修改元素切片列题推导式概念列表推导式的嵌套推导式例题学习目标了解切片的概念使用切片检索元素使用列表切片实现对列表对象修改了解推导式概念使用列表推导式创建列表6.1切片概念切片是Python序列的一种重要操作,是一种用于从序列中检索获取子序列(多个元素)的操作,适用于所有有序序列如列表、元组、字符串、range等数据类型。另外,对于可变对象如列表对象,可以通过切片操作来修改元素、包括增加、更换、删除列表中部分元素。切片语法格式切片则使用2个冒号分隔的3个数字start下标,stop下标,step步长来获取序列的多个元素,切片的语法格式如下所示:seqence[start:stop:step]其中:start:表示切片开始位置的下标,start可以省略,即切片可写为seqence[:stop:step]stop:表示切片结束位置的下标,stop可以省略,即切片可写为seqence[start::step]step:表示切片的步长,当step=1时,可以省略,同时可顺便省略最后一个冒号,即切片可写为seqence[start:stop],此时step取缺省值1。注:1.下标可以为正数:第一个元素下标为0,第二个元素下标为1,以此类推,直到len(seq)-1;2.下标也可以为负数:最后一个元素下标为-1,倒数第二个元素下标为-2,以此类推,直到-len(seq);

切片含义

切片含义(cont.)(]stopstart[)startstopstep[)startstop(]stopstart-step图中黑点表示下标的有效取值(star,step同号)

注:当start、stop符号不同且未超出索引范围时,可以通过“负数值+len(aList)”的方法,使得负数变成正数。如s[1:-4]s[1:-4+len(s)]一样,s[-4:-1]与b[-4+len(b):-2+len(b)]一样。

切片操作优点简洁性:切片操作允许您从序列(如列表、元组、字符串等)中提取子序列,而无需使用循环或其他复杂的逻辑。这使得代码更简洁、易读和易于维护。高效性:切片操作通常是在底层实现中高度优化的,因此在处理大型序列时,特别对列表对象的增加、删除、修改等操作,它们通常比手动迭代或循环更高效。健壮性:切片中的下标start与stop允许越界而不抛出异常,仅返回能遍历到的元素,start或stop会自动回缩到start,stop的默认值,而不报错,代码具有更强的健壮性。6.2用切片检索元素使用切片seqence[start:stop:step]检索元素,适用于所有有序序列如列表、元组、字符串、range等数据类型。这时seqence[start:stop:step]作为一个表达式,可以来检索获取原序列对象中的多个元素,得到由这些元素组成的一个新的序列对象;对于列表和元组对象来说,切片返回的是原序列元素的浅拷贝。step>0正向检索元素当step>0时,切片将从左到右顺序地获取原序列的多个元素,所以表达式seqence[start:stop:step]将返回顺序获取的多个元素所组成的一个新的序列对象。>>>aStr="Helloworld!">>>#

aStr[6:11]获取下标从6到11(不包括)步长为1(默认值)子字符串>>>subStr=aStr[6:11]>>>subStr'world'>>>#

aStr[1:8:2]获取从下标1到8(不包括)步长为2的子字符串>>>print(aStr[1:8:2])elo

>>>aTuple=(1,2,3,4,5,6,7,8)>>>subTuple=aTuple[1:6]>>>subTuple(2,3,4,5,6)

>>>range(10)[1:4]range(1,4)

>>>aList=[5,6,7,8,9,10,11,12,13,14]>>>subList=aList[1:8:3]>>>subList[6,9,12]

step>0正向检索元素-

start,stop可以取默认值step>0,start缺省为0(第一个元素),stop缺省为len(s)。>>>aStr="Helloworld!">>>#

aStr[:5]获取下标从0(默认值,第一个元素)到5(不包括)步长为1(默认值)子字符串>>>subStr=aStr[:5]>>>subStr'Hello'>>>#aStr[::]或aStr[:]获取原字符串的拷贝,start,stop,step均为默认值>>>print(aStr[::])elo

>>>aList=[5,6,7,8,9,10,11,12,13,14]>>>#

aList[1::3]获取下标从1到len(s)(默认值即10,不包括,但包括列表最后1个元素),步长为3子列表>>>subList=aList[1::3]>>>subList[6,9,12]>>>#aList[3::]获取下标从3到len(s)(默认值即10,不包括,但包括列表最后1个元素),步长为1(默认值)子列表>>>aList[3::][8,9,10,11,12,13,14]>>>#

aList[::2]获取下标从0(默认值,第一个元素)到len(s)(默认值即10,不包括)步长为2子列表>>>aList[::2][5,7,9,11,13]>>>#aList[:]或aList[::]获取列表的拷贝,start,stop,step均为默认值>>>newList=aList[:]>>>newList[5,6,7,8,9,10,11,12,13,14]

step>0正向检索元素-切片为原序列元素的浅拷贝>>>aList=[1,2,[3,4]]>>>#aList[::]和list(aList)、aList.copy()同效,bList为aList的浅拷贝,如下图6-2所示。>>>bList=aList[::]>>>bList[1,2,[3,4]]>>>#aList[2]、bList[2]指向同一对象,如该对象为可变对象时,需注意互相的影响

>>>aList[2]isbList[2]True>>>aList[2][1]="hello">>>bList[1,2,[3,'hello']]

step>0正向检索元素-

start、stop可以使用负数下标>>>>>aStr="Helloworld!">>>#aStr[-6:-1]获取下标从-6到-1(不包括)步长为1(默认值)子字符串,等效aStr[-6+len(aStr):-1+len(aStr)]即aStr[6:11]>>>subStr=aStr[-6:-1]>>>subStr'world'

>>>aList=[5,6,7,8,9,10,11,12,13,14]>>>#aList[-8:-1:2]获取下标从-8到-1(不包括),步长为2子列表,等效aList[-8+len(aList):-1+len(aList):2]即aList[2:9:2]>>>subList=aList[-8:-1:2]>>>subList[7,9,11,13]>>>#aList[-8:]等获取下标从-8到默认值len(aList)即10(不包括),步长为1(默认值)子列表,等效于aList[-8+len(aList):len(aList)]即aList[2:10]>>>subList=aList[-8:]>>>subList[7,8,9,10,11,12,13,14]

step>0正向检索元素-

可能获得空序列因step>0,若start下标元素在stop下标元素的右边或是同一元素,此时切片将无法从左往右顺序获取原序列的多个元素,将获得空序列。>>>aStr="Helloworld!">>>#aStr[-1:-6]无法从左到右获取下标从-1到-6(不包括),步长为1子字符串,将返回空字符串>>>subStr=aStr[-1:-6]>>>subStr''

>>>aList=[5,6,7,8,9,10,11,12,13,14]>>>#

aList[4:1]无法从左到右获取下标从4到1(不包括),步长为1子列表,将返回空列表>>>asubList=aList[4:1]>>>asubList[]>>>#aList[4:4]无法从左到右获取下标从4到4(不包括),步长为1子列表,将返回空列表>>>bsubList=aList[4:4]>>>bsubList[]

step>0正向检索元素-

start、stop可以越界start、stop可以越界,仅返回能遍历到的元素所组成的新序列(有可能为空),start或stop会自动回缩到start,stop的默认值,或者返回一个空序列,而不报错。>>>aList=[5,6,7,8,9,10,11,12,13,14]>>>#

aList[4:100]仅能获取下标从4到10(不包括)共6个元素,等效aList[4:len(subList)]即aList[4:10]>>>asubList=aList[4:100]>>>asubList[9,10,11,12,13,14]

>>>#

aList[100:400]下标从100到400(不包括)没有元素,返回空列表>>>bsubList=aList[100:400]>>>bsubList[]

>>>#

aList[-100:6]仅能获取从下标0从6(不包括)共6个元素,等效aList[0:6]>>>csubList=aList[-100:6]>>>csubList[5,6,7,8,9,10]

>>>#

aList[-100:-20]下标从-100到-20(不包括)没有元素,返回空列表>>>dsubList=aList[-100:-20]>>>dsubList[]

step<0逆向检索元素当step<0时,切片将从右到左逆序获取原序列的多个元素

,所以表达式seqence[start:stop:step]将返回逆序获取的多个元素所组成的一个新的序列对象。和step>0正向检索元素一样,返回的是原序列元素的浅拷贝,start、stop可以使用负数下标,以及start、stop可以越界。>>>aStr="Helloworld!">>>#aStr[10:0:-2]逆向获取下标从10到0(不包括)步长为-2子字符串>>>subStr=aStr[10:0:-2]>>>subStr'drwol'>>>#aStr[-1:-7:-1]逆向获取从下标-1到-7(不包括)步长为-1的子字符串>>>print(aStr[-1:-7:-1])!dlrow>>>aTuple=(1,2,3,4,5,6,7,8,[9,10])>>>#aTuple[100:2:-1]仅能获取下标从7到2(不包括)共6个元素,等效于aTuple[7:2:-1]>>>subTuple=aTuple[100:2:-1]>>>subTuple([9,10],8,7,6,5,4)>>>#因浅拷贝,aTuple[-1]和subTuple[0]是同一对象,该对象是可变对象时,需注意互相的影响>>>subTuple[0].append("hello")]>>>subTuple([9,10,'hello'],8,7,6,5,4)>>>aTuple(1,2,3,4,5,6,7,8,[9,10,'hello'])step<0逆向检索元素(cont.)当step<0时,切片将从右到左逆序获取原序列的多个元素

,所以表达式seqence[start:stop:step]将返回逆序获取的多个元素所组成的一个新的序列对象。和step>0正向检索元素一样,返回的是原序列元素的浅拷贝,start、stop可以使用负数下标,以及start、stop可以越界。>>>range(10)[9:4:-2]range(9,4,-2)

>>>aList=[5,6,7,8,9,10,11,12,13,14]>>>#

aList[-1:-10:-3]逆向获取下标从-1到-10(不包括),步长为-3子列表,等效于aList[9:0:-3]>>>asubList=aList[-1:-10:-3]>>>asubList[14,11,8]>>>#

aList[-3:-100:-1]逆向从下标-3到-100(不包括),步长为-1,仅能获取下标从-3到-len(aList)-1(不包括)共8个元素,等效aList[-3:-11:-1]>>>bsubList=aList[-3:-100:-1]>>>bsubList[12,11,10,9,8,7,6,5]>>>#aList[200:100:-1]逆向从下标200到100(不包括)没有元素,返回空列表>>>csubList=aList[200:100:-1]>>>csubList[]

step<0逆向检索元素-

start,stop默认值step<0,此时start缺省为-1(最后一个元素),stop缺省为-len(s)-1。>>>aStr="Helloworld!">>>#aStr[:5:-1]逆向获取下标从-1(默认值,最后一个元素)到5(不包括)步长为-1子字符串,等效aStr[-1:5:-1]或aStr[11:5:-1]>>>subStr=aStr[:5:-1]>>>subStr'!dlrow'>>>#aStr[::-1]获取原字符串的逆序字符串,start,stop均为默认值>>>aStr[::-1]'!dlrowolleH'

>>>aList=[5,6,7,8,9,10,11,12,13,14]>>>#aList[8::-3]逆向获取下标从8到-len(s)-1(默认值即-11,不包括)步长为-3子列表,等效aList[8:-11:-3]或aList[-2:-11:-3]>>>subList=aList[8::-3]>>>subList[13,10,7]>>>#

aList[:4:-1]逆向获取下标从-1(默认值)到4,步长为-1的子列表>>>aList[:4:-1][14,13,12,11,10]>>>#

aList[::-2]获取下标从-1(默认值)到-len(s)-1(默认值即-11,不包括)步长为-2子列表>>>aList[::-2][14,12,10,8,6]>>>#aList[::-1]获取原列表的逆序列表,start,stop均为默认值,step为-1>>>reverseList=aList[::-1]>>>reverseList[14,13,12,11,10,9,8,7,6,5]

step<0逆向检索元素-

可能获得空序列因step<0,这时若start下标元素在stop下标元素的左边或是同一元素,切片将无法从右往左逆序获取原序列的多个元素,将获得空序列。>>>aStr="Helloworld!">>>#aStr[1:6:-1]无法从右到左逆序获取下标从1到6(不包括),步长为-1子字符串,将返回空字符串>>>subStr=aStr[1:6:-1]>>>subStr''

>>>aList=[5,6,7,8,9,10,11,12,13,14]>>>#aList[1:4:-1]无法从右到左逆序获取下标从1到4(不包括),步长为-1子列表,将返回空列表>>>asubList=aList[1:4:-1]>>>asubList[]>>>#aList[4:4:-1]无法从右到左逆序获取下标从4到4(不包括),步长为-1子列表,将返回空列表>>>bsubList=aList[4:4:-1]>>>bsubList[]6.3用切片修改元素使用切片seqence[start:stop:step]修改序列对象,仅适用于可变有序序列对象——列表对象,可以通过切片来增加、修改和删除列表对象中部分元素,主要两种方式:切片出现在赋值语句的左边,即list_var[start:stop:step]=iterable,原地修改(插入、替换或删除)列表对象中的元素。这种方式根据step的取值不同又分两种情况:step等于1和step不等于1通过dellist_var[start:stop:step]可以删除列表对象中多个元素。step等于1当切片的step=1时,切片可以写成list_var[start:stop],使用切片list_var[start:stop]修改序列对象的语法格式如下所示:list_var[start:stop]=iterable

其中此时不要求切片list_var[start:stop]和iterable元素个数相等,所以原地修改列表对象list_var时,可以实现原地插入、替换或删除等。step等于1-

原地插入当切片list_var[start:stop]未获取列表对象的任何元素,即为空,而iterable含多个元素时,将会在列表的尾部、前面,或中间的位置(start所指位置)添加iterable中的多个元素。>>>#

start下标所在元素在列表最后一个元素之后,且list_var[start:stop]为空,将在列表对象尾部添加iterable中的元素,等效list_var.extend(iterable)方法>>>aList=[2,3,4,5,6]>>>aList[len(aList):][]>>>aList[len(aList):]=[7,8]#等效aList.extend([7,8])典型用法>>>aList[2,3,4,5,6,7,8]>>>aList[100:200][]>>>aList[100:200]=[9,10]#等效aList.extend([9,10])>>>aList[2,3,4,5,6,7,8,9,10]

step等于1-

原地插入(cont.)当切片list_var[start:stop]未获取列表对象的任何元素,即为空,而iterable含多个元素时,将会在列表的尾部、前面,或中间的位置(start所指位置)添加iterable中的多个元素。>>>#start下标所在元素是列表第一个元素或之前,且list_var[start:stop]为空,将在列表对象前面添加iterable中的元素>>>aList=[2,3,4,5,6]>>>aList[:0][]>>>aList[:0]=[0,1]#在列表前面添加元素典型用法>>>aList[0,1,2,3,4,5,6]>>>aList[-100:-50][]>>>aList[-100:-50]=[-2,-1]#在列表前面添加元素>>>aList[-2,-1,0,1,2,3,4,5,6]

step等于1-

原地插入(cont.)当切片list_var[start:stop]未获取列表对象的任何元素,即为空,而iterable含多个元素时,将会在列表的尾部、前面,或中间的位置(start所指位置)添加iterable中的多个元素。>>>#

list_var[start:stop]为空,start下标所在的元素在列表对象的中间,将在列表对象start位置添加iterable中的元素>>>aList=[2,3,4,5,6]>>>aList[3:3][]>>>aList[3:3]=[500,600]#在下标3位置添加元素,即500下标为3>>>aList[2,3,4,500,600,5,6]

>>>aList[4:3][]>>>aList[4:3]=[1000,2000]#在下标4位置添加元素,即1000下标为4>>>aList[2,3,4,500,1000,2000,600,5,6]

step等于1-

原地替换当切片list_var[start:stop]获取列表对象的连续范围的多个元素,而iterable也含多个元素时,列表对象这些连续范围的多个元素将被iterable中的元素替换。>>>aList=[2,3,4,5,6]>>>aList[:3][2,3,4]>>>aList[:3]=[-1,-2,-3,-4]#替换前面3个元素>>>aList[-1,-2,-3,-4,5,6]>>>aList[2:4][-3,-4]>>>aList[2:4]="hello"#替换中间的2个元素>>>aList[-1,-2,'h','e','l','l','o',5,6]>>>aList[-2:][5,6]>>>aList[-2:]=(100,200,300)#替换尾部的2个元素>>>aList[-1,-2,'h','e','l','l','o',100,200,300]

#不可以用于不可变序列对象>>>aTuple=(1,2,3,4,5,6,7,8)>>>aTuple[1:6]=(100,200)Traceback(mostrecentcalllast):File"<pyshell#104>",line1,in<module>aTuple[1:6]=(100,200)TypeError:'tuple'objectdoesnotsupportitemassignment

step等于1-

原地删除当切片list_var[start:stop]获取列表对象的连续范围的多个元素,而iterable为空序列时,列表对象这些连续范围的多个元素将被删除(可以视为原地替换的特列,即被替换成空)。>>>aList=[2,3,4,5,6]>>>aList[:3][2,3,4]>>>aList[:3]=[]#删除前面3个元素>>>aList[5,6]

>>>aList=[2,3,4,5,6]>>>aList[2:4][4,5]>>>aList[2:4]=""#删除中间的2个元素>>>aList[2,3,6]

>>>aList=[2,3,4,5,6]>>>aList[-2:][5,6]>>>aList[-2:]=()#替换尾部的2个元素>>>aList[2,3,4]

step不等于1当切片的step不等于1时,使用切片list_var[start:stop:step]=iterable原地修改列表对象时,要求切片list_var[start:stop:step]和iterable元素的个数相等,所以此时只能实现原地元素一一替换的操作。>>>aList=[5,6,7,8,9,10,11,12,13,14]>>>aList[1::3][6,9,12]>>>#切片包括3个元素,而iterable含4个元素,程序报出异常>>>aList[1::3]=[100,200,300,400]Traceback(mostrecentcalllast):File"<pyshell#5>",line1,in<module>aList[1::3]=[100,200,300,400]ValueError:attempttoassignsequenceofsize4toextendedsliceofsize3>>>aList[1::3]=[100,200,300]>>>aList[5,100,7,8,200,10,11,300,13,14]

>>>aList=list(range(10))>>>aList[0,1,2,3,4,5,6,7,8,9]>>>aList[::2]=[0]*(len(aList)//2)#保证左右两边的元素个数一样>>>aList[0,1,0,3,0,5,0,7,0,9]>>>#切片step为负数时,元素替换为逆序>>>aList=[3,4,5,6,7,9,11,12,13,14]>>>aList[:-4:-1][14,13,12]>>>aList[:-4:-1]=[100,200,300][3,4,5,6,7,9,11,300,200,100]>>>aList[::-2][100,300,9,6,4]>>>aList[::-2]=range(5)[3,4,5,3,7,2,11,1,200,0]

del切片使用del结合切片的语法格式如下所示:dellist_var[start:stop:step]

将原地删除原列表对象list_var中切片所获取的多个元素「列表list_var中从start元素(包含在切片内)开始,每隔step的元素,直到stop元素(不包含在切片内)为止」。例:使用del切片实现原地删除>>>aList=[5,6,7,8,9,10,11,12,13,14]>>>delaList[1:8]#因step=1,等效于a_list[1:8]=[]>>>aList[5,13,14]>>>aList=[5,6,7,8,9,10,11,12,13,14]>>>#因step不等于1,无法使用a_list[1:8:3]=[]因左右两边不相等>>>aList[1:8:3]=[]Traceback(mostrecentcalllast):File"<pyshell#8>",line1,in<module>aList[1:8:3]=[]ValueError:attempttoassignsequenceofsize0toextendedsliceofsize3>>>delaList[1:8:3]#只能使用del>>>aList[5,7,8,10,11,13,14]>>>aList=[5,6,7,8,9,10,11,12,13,14]>>>delaList[-1:-10:-3]>>>aList[5,6,7,9,10,12,13]

>>>aList=[5,6,7,8,9,10,11,12,13,14]>>>delaList[-3:-100:-1]#可以下标越界,仅删除获取的元素>>>aList[12,13]>>>aList=[5,6,7,8,9,10,11,12,13,14]>>>delaList[200:100:-1]#切片未获取任何元素,所以没有删除任何元素>>>aList[5,6,7,8,9,10,11,12,13,14]>>>aList=[5,6,7,8,9,10,11,12,13,14]>>>delaList[200:100:-1]#切片未获取任何元素,所以没有删除任何元素>>>aList[5,6,7,8,9,10,11,12,13,14]>>>#同样不可以用于不可变序列对象>>>aStr="Helloworld!">>>delaStr[6:11]Traceback(mostrecentcalllast):File"<pyshell#8>",line1,in<module>delaStr[6:11]TypeError:'str'objectdoesnotsupportitemdeletion

6.4切片例题例1:筛选字符串对列表中的字符串['apple','slowly','angrily','dog','quickly','fish','hopefully','goat','horse','carefully','easily','monkey','owl','happily','beautifully','sheep','zebra']进行统计,筛选出其中以'ly'单词,并统计其数量。代码6‑1:slicing_demo1.py

defmain():words=['apple','slowly','angrily','dog','quickly','fish','hopefully','goat','horse','carefully','easily','monkey','owl','happily','beautifully','sheep','zebra']ly_words=[]forwordinwords:#使用切片word[-2:]获得单词最后两个字符,以判定是否是`ly`ifword[-2:]=="ly":ly_words.append(word)print("共有%d个单词以ly结尾:"%len(ly_words))print(",".join(ly_words))

if__name__=="__main__":main()

例2:实现字符串字符的错位打印用户随意输入一串字符,程序依次在相邻位置插入一个空格,逐行输出,使得程序的输出效果为:defmain():s=input('请输入一串字符串:')iflen(s)>1:#字符串长度为1时foriinrange(1,len(s)):print(s[:-i],end='')#使用切片打印空格前的字符print(s[-i:])#使用切片打印空格前的字符print("------")foriinrange(1,len(s)):print(s[:i],end='')#使用切片打印空格前的字符print(s[i:])#使用切片打印空格前的字符eliflen(s)==1:#字符串长度为1时print(s)print('-----')print(s)else:print("字符串是空的,不对哦")#字符串为空时if__name__=="__main__":

main()

代码6‑2:slicing_demo2.py

例3:实现对列表左移位以列表[10,20,30,40,50,60,70,80,90]为例:如果左移1位,列表变为[20,30,40,50,60,70,80,90,10],如果左移2位,列表变为[30,40,50,60,70,80,90,10,20],如果左移3位,列表变为[40,50,60,70,80,90,10,20,30],……如果左移9位,列表就还原了,如果左移10位,与如果左移1位一样,以此类推。defleft_shift(orgList,times):#当times>aList的长度时,左移times相当于左移times%len(aList)times=times%len(orgList)#使用切片获得列表左移后剩下的部分orgList[times:],以及左移的部分orgList[:times]returnorgList[times:]+orgList[:times]defmain():myList=list(range(1,10))shiftedList=left_shift(myList,3)print("Originallist:",myList)print("Shiftedlist:",shiftedList)if__name__=="__main__":main()

代码6‑3:slicing_demo3.py

例4:实现原地对列表左移位实现原地对列表左移位。修改例3的程序,实现对列表原地的修改,而不是生成新的列表。defleft_shiftself(aList,times):#当times>aList的长度时,左移times相当于左移times%len(aList)times=times%len(aList)#使用切片左移的部分aList[:times]并删除shiftPart=aList[:times]delaList[:times]#将左移的部分原地添加到列表尾部aList[len(aList):]=shiftPartdefmain():myList=list(range(1,10))print("Beforeshift:",myList)shiftedList=left_shiftself(myList,3)print("Aftershift:",myList)if__name__=="__main__":main()

代码6‑4:slicing_demo4.py

6.5推导式的概念推导式或者说解析式(comprehension),是Python风格代码一种非常简洁的创建序列的方式,可以使用简洁程序语句创建列表,字典,集合等对象,最常用的是列表推导式。传统for循环代码VS.列表推导式代码创建列表:for循环方式:odddata=[]#创建空列表forxinrange(20):ifx%2:#如果x为奇数,则添加

到odddataodddata.append(x)print(odddata)#输出:[1,3,5,7,9,11,13,15,17,19]

列表推导式方式:只需要一行代码即可,非常简洁,具有较强可读性

相较于for循环更高效,因为列表推导式在执行时调用的是Python的底层C代码,而for循环则是用Python代码来执行odddata=[xforxinrange(20)ifx%2]print(odddata)#输出:[1,3,5,7,9,11,13,15,17,19]

含一个for/if子句的列表推导式new_list=[]for变量in序列:if条件:new_list.append(表达式)

对于创建列表对象来说,简单列表推导式含有一个for/if子句,其语法格式如下所示:[表达式for变量in可迭代对象]或[表达式for变量in序列if可迭代对象]

其中:for变量in可迭代对象[if条件]可选决定所创建的列表对象中元素的个数表达式将在每次循环并满足条件时,生成所创建的列表中的每个元素以上列表推导式等效于下面代码:含一个for/if子句的列表推导式-不使用if子句最简单列表推导式可以不含if子句,示例代码如下:>>>numsList=[10*nforninrange(10)]>>>numsList[0,10,20,30,40,50,60,70,80,90]

>>>#上面的代码与下面的代码是等效的:>>>numsList=[]>>>forninrange(10):

numsList.append(10*n)>>>numsList[0,10,20,30,40,50,60,70,80,90]

含一个for/if子句的列表推导式-使用if子句可以使用if子句从序列中筛选符合条件的元素,示例代码如下:>>>numsList=[-2,5.3,7,8.6,-7.4,-9,10.2]>>>#

筛选出大于0的数>>>resultList=[numfornuminnumsListifnum>0]>>>resultList[5.3,7,8.6,10.2]>>>#上面的代码与下面的代码是等效的:>>>resultList=[]>>>fornuminnumsList:

ifnum>0:

resultList.append(num)>>>resultList[5.3,7,8.6,10.2]

>>>#筛选出是int类型的数>>>resultList=[numfornuminnumsListifisinstance(num,int)]>>>resultList[-2,7,-9]>>>#上面的代码与下面的代码是等效的:>>>resultList=[]>>>fornuminnumsList:

ifisinstance(num,int):

resultList.append(num)>>>resultList[-2,7,-9]

含一个for/if子句的列表推导式-使用函数或复杂表达式列表推导式的表达式可以是函数或复杂表达式,示例代码如下:>>>#

使用函数,如求绝对值:>>>numsList=[-2,5.3,7,8.6,-7.4,-9,10.2]>>>[abs(num)fornuminnumsList][2,5.3,7,8.6,7.4,9,10.2]

>>>#

使用对象方法,如字符串对象处理:>>>userList=['Tommy','Alice','Jack','WangMing']>>>[user.strip()foruserinuserList]#去掉前后空格处理['Tommy','Alice','Jack','WangMing']

>>>groupList=['Alice,Tom,Jack,Owen','Mary,John,David','Ashley,Emma','Jessica,Julia']>>>[group.split(",")forgroupingroupList]#分割字符串处理[['Alice','Tom','Jack','Owen'],['Mary','John','David'],['Ashley','Emma'],['Jessica','Julia']]

>>>#

表达式可以创建一个序列,如元组>>>numsList=[-2,5.3,3-4j,-9]>>>[(num,abs(num))fornuminnumsList][(-2,2),(5.3,5.3),((3-4j),5.0),(-9,9)]

>>>#也可以用ifelse表达式>>>numsList=[-2,5.3,7,8.6,-7.4,-9,10.2]>>>[numifnum>0else-numfornuminnumsListifisinstance(num,int)][2,7,9]

含多个for/if子句的列表推导式new_list=[]for变量1in序列1:if条件1:for变量2in序列2:if条件2:for变量3in序列3:if条件3:......

for变量Nin序列N:if条件N:new_list.append(表达式)

列表推导式在第一个for之后可以跟多个for或if子句,其语法格式如下所示:[表达式for变量1in可迭代对象1if条件1 for变量2in可迭代对象2if条件2 for变量3in可迭代对象3if条件3 ... for变量Nin可迭代对象Nif条件N]

该列表推导式等效于下面代码:例:使用多个for/if子句>>>#

实现嵌套列表的平铺:>>>numMatrix=[[1,2,3,4],[5,6,7,8],[9,10,11,12]]>>>[colforrowinnumMatrixforcolinrow][1,2,3,4,5,6,7,8,9,10,11,12]>>>groupList=[['Alice','Tom','Jack','Owen'],['Mary','John','David'],['Ashley','Emma'],['Jessica','Julia']]>>>[userforgroupingroupListforuseringroup]['Alice','Tom','Jack','Owen','Mary','John','David','Ashley','Emma','Jessica','Julia’]>>>#

上面的代码与下面的代码是等效的:>>>userList=[]>>>forgroupingroupList:

foruseringroup:

userList.append(user)>>>#

生成两位数偶数的列表>>>evenList=[x*10+yforxinrange(10)ifx!=0foryinrange(10)ify%2==0]>>>evenList[10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,94,96,98]

>>>#上面的代码与下面的代码是等效的:>>>evenList=[]>>>forxinrange(10):ifx!=0:foryinrange(10):ify%2==0:evenList.append(x*10+y)

其他类型推导式字典推导式集合推导式生成器推导式其他类型推导式-

字典推导式>>>scores=[['Alice',90],['Bob',80],['Carol',70],['Tom',45]]

>>>#

生成字典对象>>>score_dict={name:scoreforname,scoreinscores}>>>score_dict{'Alice':90,'Bob':80,'Carol':70,'Tom':45}>>>#上面的代码与下面的代码是等效的:>>>score_dict={}>>>forname,scoreinscores:score_dict[name]=score

>>>#筛选出及格学生,生成字典对象>>>scores=[['Alice',90],['Bob',80],['Carol',70],['Tom',45]]>>>pass_dict={name:scoreforname,scoreinscoresifscore>=60}>>>score_dict{'Alice':90,'Bob':80,'Carol':70}>>>#上面的代码与下面的代码是等效的:>>>pass_dict={}>>>forname,scoreinscores:ifscore>=60:pass_dict[name]=score>>>#

字典推导式也可以使用多个for/if子句,其含义和列表推导式一样>>>{(real,imag):real+imag*1jforrealinrange(1,6)forimaginrange(1,6)ifreal!=imag}{(1,2):(1+2j),(1,3):(1+3j),(1,4):(1+4j),(1,5):(1+5j),(2,1):(2+1j),(2,3):(2+3j),(2,4):(2+4j),(2,5):(2+5j),(3,1):(3+1j),(3,2):(3+2j),(3,4):(3+4j),(3,5):(3+5j),(4,1):(4+1j),(4,2):(4+2j),(4,3):(4+3j),(4,5):(4+5j),(5,1):(5+1j),(5,2):(5+2j),(5,3):(5+3j),(5,4):(5+4j)}

字典推导式的语法格式如下所示,具有两个表达式:key表达式与value表达式,同时定界符为字典定界符{}

{key表达式:value表达式for变量in可迭代对象}或{key表达式:value表达式for变量in可迭代对象if条件}

其他类型推导式-

集合推导式>>>#获取字符串的长度,并去重>>>userName=['Alice','Tom','Jack','Owen','Mary','John','David','Ashley','Emma','Jessica','Julia']>>>{len(nameStr)fornameStrinuserName}{3,4,5,6,7}

>>>#

筛选符合长度的字符串,并去重>>>userName=['Alice','Tom','Jack','Owen','Mary','John','David','Ashley','Emma','Jessica','Julia']>>>{nameStrfornameStrinuserNameiflen(nameStr)==4}{'Emma','Jack','John','Mary','Owen'}

>>>#集合推导式也可以使用多个for/if子句,其含义和列表推导式一样>>>course=['Math','Chinese','Science','Python']>>>score=[99,89,80,95]>>>{(c,s)forc,sinzip(course,score)ifs<60}{('Chinese',55),('Python',45)}

集合推导式的语法格式如下所示,定界符为集合定界符{}

{表达式for变量in可迭代对象}或{表达式for变量in可迭代对象if条件}其他类型推导式-

生成器推导式如果列表推导式所使用的方括号,在形式上改成圆括号作为定界符,这时就成为了生成器推导式,生成器推导式语法格式如下所示,生成器推导式也可以使用多个for/if子句,其含义和列表推导式一样:(表达式for变量in可迭代对象)

或(表达式for变量in可迭代对象if条件)需要注意的是:生成器推导式并不是元组推导式,所以并不是创建元组对象,而是创建了一个生成器对象。生成器对象类似于迭代器对象,具有惰性求值的特点,只在需要时才生成新元素,比列表推导式具有更高的效率,空间占用非常少,更适合大数据处理的场合。可使用生成器对象的__next__()方法(Python3.x)进行遍历,也可采用内置函数next(obj)(Python2.x采用next()方法),生成器对象访问时元素指针会往前移动。所有元素访问结束时,下一个元素会抛出异常StopIteration只能从前往后正向访问每个元素,没有任何方法可以再次访问已访问过的元素,也不支持使用下标、切片访问其中的元素。当所有元素访问结束以后,如果需要重新访问其中的元素,必须重新创建该生成器对象。例:生成器推导式>>>gtor=(n*10forninrange(10))>>>gtor<generatorobject<genexpr>at0x105e358a0>

>>>#使用生成器对象的__next__()方法,生成新的元素>>>gtor.__next__()0>>>gtor.__next__()10>>>next(gtor)20>>>next(gtor)30

>>>#可根据需要将其转换为列表或元组,注意访问过的元素不再存在,只能生成新的元素>>>list(gtor)[40,50,60,70,80,90]>>>#

生成器对象已遍历结束,没有元素了>>>tuple(gtor)()

>>>#

重新创建生成器对象,转换为元组对象>>>gtor=(n*10forninrange(10))>>>tuple(gtor)(0,10,20,30,40,50,60,70,80,90)

6.6列表推导式的嵌套在列表推导式中,如果表达式,或者for/if子句中也含有推导式,那么就形成了列表推导式的嵌套,可以较为简洁地解决复杂的问题。。例:列表推导式的嵌套>>>#实现二维矩阵转置,即行变为列,列变为行(表达式中含有推导式)>>>matrix=[[1,2,3],[4,5,6],[7,8,9]]>>>trans=[[row[i]forrowinmatrix]foriinrange(len(matrix[0]))]>>>trans[[1,4,7],[2,5,8],[3,6,9]]>>>#外层推导式的循环用于遍历每一列的索引,内层推导式的循环用于遍历每一行,并将每一行中对应索引的元素放入新的列表中

>>>#求整数n以内所有的质数(for/if子句中含有推导式)>>>n=50>>>[numfornuminrange(2,n)if0notin[num%iforiinrange(2,int(n**0.5)+1)]][11,13,17,19,23,29,31,37,41,43,47]>>>#[num%iforiinrange(2,int(n**0.5)+1)]生成num除以它可能因子的余数,如没有0,说明其是质数

6.7推导式例题例1:筛选字符串(列表推导式版)

对列表中的字符串['apple','slowly','angrily','dog','quickly','fish','hopefully','goat','horse','carefully','easily','monkey','owl','happily','beautifully','sheep','zebra']进行统计,筛选出其中以'ly'单词,并统计其数量。代码6‑5:comprehension

_demo1.py

defmain():words=['apple','slowly','angri

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论