资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,2017/6/6 Tuesday,重庆邮电大学硕士学位论文终期答辩,#,2017/6/6 Tuesday,重庆邮电大学硕士学位论文终期答辩,2025/1/7 周二,第,3,章 组合数据类型,主 讲 人:,目录,2025/1/7 周二,2,1.,列表,2.,元组,3.,字典,4.,集合,5.,组合数据类型的高级特性,2025/1/7 周二,1.,列表,Python,内置的一种数据类型是列表,(list),。,list,是一种最具灵活性的有序集合对象类型,可以随时添加和删除其中的元素。,2025/1/7 周二,1.,列表,1.1,创建列表,通常,使用左右方括号(即:,和,)将数据元素包裹起来创建一个列表,如下所示,。,其中列表,list1,中包含,5,个元素,分别是,1,、,2,、,3,、,4,、,5,,,list1,为列表名。这种创建列表的方式适用于对于列表中元素个数及其数值已知时。,List1=1,2,3,4,5,List2=a,b,c,d,2025/1/7 周二,1.,列表,1.1,创建列表,当遇到如将一个元组(参考,3.2,节)转换为列表时,则需要使用另外一种方法创建列表,调用,list(tuple),函数,该函数返回一个包含,tuple,中所有元素的列表。,注:直接调用不带参的,list(),函数时,将返回一个空列表,即:,。,2025/1/7 周二,1.,列表,1.1,创建列表,列表中的元素的数据类型可以各不相同,如,int,,,string,类型,甚至可以是一个列表类型,如在下例中,10,20,为一个,list,类型,它作为,list3,的一个元素存在于,list3,中。,List3=marry,2.0,5,10,20,List3,marry,2.0,5,10,20,2025/1/7 周二,1.,列表,1.1,创建列表,如图,3-1,所示,列表的下标是从,0,开始,,List3,列表的第一个元素是,marry,,用,L0,可以表示,L,的第一个元素,第二个元素是,2.0,,用,L1,表示,以此类推,第四个元素是一个列表,即,10,20,。,图,3-1,元组索引位置,2025/1/7 周二,1.,列表,1.2,读取,元素,元素下标表示该元素在,list,中的位置。注意,list,中元素下标是从,0,开始的,如第,n,个元素下标为,n-1,。但当读取元素传入的元素下标超出,list,集合的大小时将会报“元素下标超出范围”的错误。,2025/1/7 周二,1.,列表,1.2,读取,元素,List2=a,b,c,d,List20#,访问列表的第一个元素,a,List21#,访问列表的第二个元素,b,List25#,超出列表元素下标,报错,Traceback(most recent call last):,File,line 1,in,List25,IndexError:list index out of range,由于,list2,的长度为,4,,在取第,5,个元素时,,list2,中元素的最大下标为,3 List2-1,d,List2-2,c,List2-3,b,List2-5#,超出列表元素下标,报错,Traceback(most recent call last):,File,line 1,in,List2-5,IndexError:list index out of range,除了正向取,list,中的元素外,也可以逆向去取,用元素下标,-1,表示最后一个元素,,-2,表示倒数第二个元素,同样注意不能超出元组个数的界限,例如:,。,2025/1/7 周二,1.,列表,1.3,遍历列表,for cheese in cheeses:,print(cheese),遍历一个列表元素的最常见方式是使用,for,循环,常见的有以下两种方式。,第一种遍历方法隐藏了列表,cheeses,的长度,操作较为便利。,2025/1/7 周二,1.,列表,1.3,遍历列表,for i in range(len(numbers):,numbersi=numbersi*2,第二种遍历方法则使用,len(),函数计算出列表,numbers,的长度后进行遍历操作,其中,range(),函数返回的是从,0,到,numbers,长度的数值序列。,2025/1/7 周二,1.,列表,1.4,替换元素,numbers=12,13,numbers1=14,numbers,12,14,和,字符串不同的是,列表是可变的,可以在列表中指定下标的值对元素进行修改,例如:,numbers1,原先为,13,,当执行,numbers1=14,时,,numbers1,的值被修改为,14,。,2025/1/7 周二,1.,列表,1.5,增加元素,list=1,list=list+a,b,list,1,a,b,*,操作符重复一个列表多次:,0*5,0,0,0,0,0,4,5,6*4,4,5,6,4,5,6,4,5,6,4,5,6,方法一:使用“,+”,将一个新列表附加在原列表的尾部。例如:,和,字符串不同的是,列表是可变的,可以在列表中指定下标的值对元素进行修改,例如:,2025/1/7 周二,1.,列表,1.5,增加元素,list.append(True),list,1,a,b,True,方法二:使用,append(),方法向列表的尾部添加一个新元素。例如:,list.extend(c,5),list,1,a,b,True,c,5,方法三:使用,extend(),方法将一个列表添加在原列表的尾部。例如:,2025/1/7 周二,1.,列表,1.5,增加元素,list.insert(0,x),list,x,1,a,b,True,c,5,方法四:使用,insert(),方法将一个元素插入到列表的指定位置。该方法有两个参数,第一个参数为插入位置,第二个参数为插入元素。例如:,2025/1/7 周二,1.,列表,1.6,检索,元素,list=x,y,a,b,True,x,list.count(x),2,使用,count(),方法计算列表中某个元素出现的次数。,3 in list,False,x in list,True,使用,in,运算符检查某个元素是否在列表中。,2025/1/7 周二,1.,列表,1.6,检索,元素,使用,index(),方法返回某个元素在列表中的准确位置,若该元素不在列表中将会出错。值得注意的是,若使用该方法的元素在该列表中存在相同项,则返回显示最小,index,的位置,如,list.index(x),,存在两个,x,,则只显示最小位置。,list.index(x),0,1.,列表,1.7,删除元素,方法一:使用,del,语句删除某个特定位置的元素。,list=x,y,a,b,True,x,del list1,list,x,a,b,True,x,1.,列表,1.7,删除元素,方法二:使用,remove(),方法删除某个特定值的元素。,remove(x),从,list,中移除最左边出现的数据项,x,,如果找不到,x,就产生,ValueError,。,list=x,y,a,b,True,x,list.remove(x),list,y,a,b,True,x,list.remove(x),list,y,a,b,True,list.remove(x),Traceback(most recent call last):,File,line 1,in,list.remove(x),ValueError:list.remove(x):x not in list,1.,列表,1.7,删除元素,方法三:使用,pop(),方法来弹出(删除)指定位置的元素,缺省参数时弹出最后一个元素。弹出空数组将会报错。,list=x,y,a,b,True,x,list.pop(),x,list,x,y,a,b,True,list.pop(1),y,list,x,a,b,True,list.pop(1),a,1.,列表,1.7,删除元素,list.pop(1),b,list.pop(1),True,list.pop(),x,list,list.pop(),Traceback(most recent call last):,File,line 1,in,list.pop(),IndexError:pop from empty list,接上一页,PPT,1.,列表,1.8,字符串和列表的转化,s=Micheal,t=list(s),t,M,i,c,h,e,a,l,字符串是字符的序列,而列表是值的序列,但字符的列表和字符串并不相同。若要将一个字符串转化为一个字符的列表,可以使用函数,list,。,1.,列表,1.8,字符串和列表的转化,s=you are so beautiful,t=s.split(),t,you,are,so,beautiful,由于,list,是内置函数的名称,所以应当尽量避免使用它作为变量名称。,list,函数会将字符串拆成单个的字母。如果想要将字符串拆成单词,可以使用,split,方法。,1.,列表,1.8,字符串和列表的转化,u=www.studyP,d=u.split(),d,www.studyP,但是下面的例子却失败了,输出了整个列表。,u=www.studyP,c=u.split(.),c,www,studyPython,com,cn,这时候就要用,split,接受一个可选的形参,作为分隔符,用于指定用哪个字符来分割单词。例如上面的例子可以用一个“,.,”作为分隔符,如下所示。,1.,列表,1.8,字符串和列表的转化,join,是,split,的逆操作。它接收字符串列表,并拼接每个元素。,join,是字符串的方法,所以必须在分隔符上调用它,并传入列表作为实参。,t=you,are,so,beautifil,s=.join(t),s,you are so beautifil,1.,列表,1.8,列表的常用函数,cmp,(),格式,:,cmp(,列表,1,列表,2),。,功能,:对两个列表进行比较,若第一个列表大于第二个,则结果为,1,,相反则为,-1,,元素完全相同则结果为,0,。,list1=123,xyz,list2=123,abc,cmp(list1,list2),1,cmp(list2,list1),-1,list2=list1,cmp(list1,list2),0,1.,列表,1.8,列表的常用函数,len(),格式,:,len(,列表,),。,功能,:返回列表中的元素个数。,len(list1),2,1.,列表,1.8,列表的常用函数,max(),和,min(),格式,:,max(,列表,)min(,列表,),。,功能,:返回列表中的最大或最小元素。,str_l=abc,xyz,123,num_l=123,456,222,max(str_l),xyz,min(str_l),123,max(num_l),456,min(num_l),123,1.,列表,1.8,列表的常用函数,sorted(),和,resersed(),格式,:,sorted(,列表,)reversed(,列表,),。,功能,:前者的功能是对列表进行排序,默认是按升序排序,还可在列表的后面增加一个,reverse,参数,其等于,True,则表示按降序排序;后者的功能是对列表进行逆序。,list=1,4,3,6,9,0,2,for x in reversed(list):,print x,2 0 9 6 3 4 1,sorted(list),0,1,2,3,4,6,9,sorted(list,reverse=True),9,6,4,3,2,1,0,1.,列表,1.8,列表的常用函数,sum(),格式:,sum(,列表,),。,功能:,对数值型列表的元素进行求和运算,对非数值型列表运算则出错。,sum(list),25,sum(str_l),Traceback(most recent call last):,File,line 1,in,sum(str_l),TypeError:unsupported operand type(s)for+:int and str,目录,2025/1/7 周二,2,1.,列表,2.,元组,3.,字典,4.,集合,5.,组合数据类型的高级特性,2,.,元组,元组(,tuple,)是值的一个序列。其中的值可以是任何类型,并且按照整数下标索引,与列表类似。但元组中的元素不能修改,列表中的元素可以修改。,2,.,元组,2.1,元组与列表的区别,元组基本上都是不可改变的列表。元组几乎具有列表所有的特性,除开那些违反不变性的特征。也就是说,没有函数和方法可以改变元组。,不可变的,tuple,有什么意义?,因为,tuple,不可变,所以代码更安全。如果可能,能用,tuple,代替,list,就尽量用,tuple,。当后续介绍字典类型时,会发现字典的键必须是不可变的,因此元组可以用作字典的键,但列表不能。,2,.,元组,2.1,元组与列表的区别,语法上,元组就是用逗号分隔的一列值,使用“,=”,将元组赋给变量。,tuple1=a,1,boy,虽然并不必需,但元组常常用括号括起来。,tuple1=(a,1,boy),tuple1,(a,1,boy),2,.,元组,2.1,元组与列表的区别,新建元组的另一种形式是使用内置函数,tuple,。不带参数时,它会新建一个空元组。,t=tuple(),t,(),2,.,元组,2.1,元组与列表的区别,则定义的不是,tuple,,是,1,这个数!这是因为括号,(),既可以表示,tuple,,又可以表示数学公式中的小括号,这就产生了歧义。因此,,Python,规定,这种情况下,按小括号进行计算,计算结果自然是,1,。所以,只有一个元素的,tuple,定义时必须加一个逗号“,”来消除歧义,即:,t=(1,),t,(,1,),但是,要定义一个只有一个元素的,tuple,,例如:,t=(1),t,1,2,.,元组,2.1,元组与列表的区别,其他序列(列表和字符串)的操作都可用于元组,除了那些会违反不变性的列表运算符。,“,+”,和“*”运算符同样适用于元组。,成员操作(,in,)和,for,循环同样适用于元组,长度(,len,)、最大(,max,)和最小(,min,)同样适用于元组。,没有任何的操作能更改元组。例如,append,、,extend,、,insert,、,remove,、,pop,、,reverse,和,sort,不能用于元组。,2,.,元组,2.2,元组的常用操作,由于元组和列表比较相似,使得对列表的很多操作如“,+,”、“,*,”等运算符以及长度(,len,)、最大(,max,)、最小(,min,)等运算都适用于元组。而那些如,append,、,extend,、,insert,、,remove,、,pop,、,reverse,和,sort,等能改变元素的操作都不能直接操作元组。,然而,当元组中存在列表元素项时,就可以使用上述如,append,等方法修改,list,中的元素,达到间接修改元组元素的目的。,2,.,元组,2.3,元组的常用函数,元组的常用函数与列表类似,除了那些会违反不变性的函数。,语,法,描,述,cmp(tuple1,tuple2),比较两个元组元素,len(tuple),计算元组元素个数,max(tuple),返回元组中元素最大值,min(tuple),返回元组中元素最小值,tuple(seq),将列表转换为元组,表,3-1,元组的常用函数,目录,2025/1/7 周二,2,1.,列表,2.,元组,3.,字典,4.,集合,5.,组合数据类型的高级特性,3.,字典,字典是一种集合,它不是序列。字典可以看成元素对构成的列表,其中一个元素是键,另一个元素是值。在搜索字典时,首先查找键,当查找到键后就可以直接获取该键对应的值,效率很高,是一种高效的查找方法。,3.,字典,3.1,创建字典,与列表、元组不同的是,字典是以“,”和“,”定义的,而且字典中每个元素包含两个部分,即键和值。下面给出了一些实例,展示了各种语法,这些语法产生的是相同的字典。,3.,字典,3.1,创建字典,d1=dict(id:19,name:Marry,city:chongqing),d2=dict(id=19,name=Marry,city=chongqing),d3=dict(id,19),(nmae,Marry),(city,chongqing),d4=dict(zip(id,name,city),(19,Marry,chongqing),d5=id:19,name:Marry,city:chongqing,d1,name:Marry,id:19,city:chongqing,d2,name:Marry,id:19,city:chongqing,d3,name:Marry,id:19,city:chongqing,d4,name:Marry,id:19,city:chongqing,d5,name:Marry,id:19,city:chongqing,3.,字典,3.2,查找与反向查找,d1id,19,d1name,Marry,d1chongqing,Traceback(most recent call last):,File,line 1,in,d1chongqing,KeyError:chongqing,字典,定义好后,可以通过键来查找值,这个操作称为“查找”。,3.,字典,3.2,查找与反向查找,def reverse_lookup(d,v):,for k in d:,if dk=v:,return k,raise LookupError,(),对于字典的操作通常是通过键来查找值,而能不能通过一个给定的值来确定其键呢,?,由于,字典是一对多的关系,即一个键可能对应多个值,若想根据一个值来确定其键时,只能通过暴力搜索的方法。下面给出一个简单的暴力搜索实例,该段代码接收一个值,并返回映射到该值的键:,3.,字典,3.3,遍历字典,for key in d1.keys():,print(key,d1key),name,Marry,id 19,city Chongqing,用循环语句来遍历字典中的每个元素的键和值,如下所示:,3.,字典,3.4,添加和修改字典,d1name=jason,d1,name:jason,id:19,city:chongqing,d1sex=female,d1,sex:female,name:jason,id:19,city:chongqing,字典的大小和列表都是动态的,即不需要事先指定其容量大小,可以随时向字典中添加新的键,值对,或者修改现有键所关联的值。添加和修改的方法相同,都是使用“字典变量名,键名,=,键值”的形式,主要区分在于字典中是否已存在该键,值对,若存在则为修改,否则为添加。例如:,3.,字典,3.4,添加和修改字典,d1name=jason,d1,name:jason,id:19,city:chongqing,d1sex=female,d1,sex:female,name:jason,id:19,city:chongqing,例如:,d1=dict(id:19,name:Marry,city:chongqing),,,d1,中已经存在,name,键,值对,所以第一个操作是“修改”。,d1,中原本不存在,sex,键,值对,所以第二个操作是“添加”。,因为字典是无序的,类似于,append,在尾部添加键,值对的方法是没有任何意义的。,3.,字典,3.5,字典长度,len(d1),4,与列表、元组相同,可以用,len(),函数返回字典中键的数量,如下所示。,3.,字典,3.6,字典检索,id in d1,True,name in d1,True,NO in d1,False,可以使用,in,运行符来测试某个特定的键是否在字典中。表达式,k in d,(,d,为字典)查找的是键,而不是值。,3.,字典,3.6,字典检索,d1=sex:female,name:jason,id:19,city:chongqing,vals=d1.values(),jason in vals,True,查看一个值是不是出现在字典中,可以使用方法,values,,它返回该字典的所有值的一个集合,然后检索当前值是否在集合中即可,例如:,3.,字典,3.7,删除元素和字典,可以,使用,del,语句删除指定键的元素或整个字典;,使用,clear,(),方法来删除字典中所有元素;,使用,pop(),方法删除并返回指定键的元素;,popitem,(),弹出随机的项。,3.,字典,3.8,字典的常用函数,copy,(),:,返回一个具有相同键值对的新字典,该新字典是原来字典的一个副本(这个方法实现的是浅拷贝),。,fromkeys(),:,使用给定的键建立新的字典,每个默认对应的值为,None,。,get(),:,get,方法是一个更宽松的访问字典项的方法。一般来说,如果试图访问字典中不存在的项时会,出错,。,items(),:,items,方法将所有的字典项以列表的方式返回,这些列表项中的每一项都来自于,(,键,值,),。,3.,字典,3.8,字典的常用函数,keys(),:,将字典中的键以列表形式返回,。,setdefault(),:能够获得与给定键相关联的值,除此之外,,setdefault,还能在字典中不含有给定键的情况下设定相应的键值,。,update(),:,利用一个字典项更新另一个字典,若有相同的键存在,则会进行覆盖。,目录,2025/1/7 周二,2,1.,列表,2.,元组,3.,字典,4.,集合,5.,组合数据类型的高级特性,4,.,集合,集合,(,set,)是,0,个或多个对象引用的无序组合,这些对象所引用的对象都是可哈希运算的。集合是可变的,因此可以很容易地添加或移除数据项,但由于其中的项是无序的,因此,没有索引位置的概念。,在,集合中,任何元素都没有重复,这是集合的一个非常重要的特点。,set,和,dict,类似,是一组,key,的集合,但不存储,value,,且在,set,中没有重复的,key,。,4,.,集合,4.1,创建集合,可以通过调用集合的构造函数来创建一个集合。和前文许多其他数据结构不同,创建集合没有快捷方式。因此,要创建集合,必须使用,set,构造函数。,set,构造函数至多有一个参数。如果没有参数,,set,会创建空集。如果有一个参数,那么参数必须是可迭代的,例如字符串或列表,可迭代对象的元素将生成集合的成员。,4,.,集合,4.1,创建集合,没有,参数,,set,会创建空集,。,nullSet=set(),nullSet,set,(),提供一个,str,作为输入集合,创建一个,set,。,a_set=set(abcd),a_set,a,c,b,d,提供一个,list,作为输入集合,创建一个,set,。,s=set(1,2,3),s,1,2,3,重复元素在,set,中自动被过滤。,s=set(1,1,2,2,3,3),s,1,2,3,4,.,集合,4.2,添加元素,通过,add(key),方法可以添加元素到,set,中,可以重复添加,但不会有效果。例如:,s.add(4),s,1,2,3,4,s.add(4),s,1,2,3,4,4,.,集合,4.3,删除元素,通过,remove(key),方法可以删除元素。例如:,discard(key,),也可删除元素,不同的是,如果删除的元素不在集合中,,remove,会报错,,discard,不会报错。例如,:,clear,(),删除集合的所有元素(使它成为空集)。,4,.,集合,4.4,典型的集合运算符,len(),:和所有集合类型一样,,len,函数可以确定集合中的元素数量。,in,:判断某元素是否在集合中。,in,运算符根据元素是否在集合中返回布尔值,True,或,False,。,for,:和所有集合类型一样,,for,语句能遍历集合中的元素。,4,.,集合,4.5,典型的数学集合运算,交集,s1=set(1,2,3),s2=set(2,3,4),s1.intersection(s2),2,3,s1&s2,2,3,4,.,集合,4.5,典型的数学集合运算,并,集,s1.union(s2),1,2,3,4,s1|s2,1,2,3,4,4,.,集合,4.5,典型的数学集合运算,差集,s1.difference(s2),1,s2.difference(s1),4,s1-s2,1,s2-s1,4,4,.,集合,4.5,典型的数学集合运算,对称差,s1.symmetric_difference(s2),1,4,s2.symmetric_difference(s1),1,4,4,.,集合,4.5,典型的数学集合运算,子集和超集,sSet=set(1,2,3),bSet=set(1,2,3,4,5,6),sSet.issubset(bSet),True,bSet.issubset(sSet),False,sSet.issuperset(bSet),False,bSet.issuperset(sSet),True,sSet.issubset(sSet),True,sSet.issuperset(sSet),True,4,.,集合,4.6,集合的常用函数,前一小节集合的常用操作已经把集合的用法介绍得差不多了,这里就补充几个集合的常用函数,如表,3-2,所示。,语,法,描,述,s.copy(),返回一个新集合,它是集合,s,的浅拷贝,s.update(t),用,t,中的元素修改,s,,即,s,现在包含,s,或,t,的成员,s.intersection_update(t),s,中的成员是共同属于,s,和,t,的元素,s.symmetric_difference_update(t),s,中的成员更新为那些包含在,s,或,t,中,但不是,s,和,t,共有的元素,表,3-2,集合的常用函数,目录,2025/1/7 周二,2,1.,列表,2.,元组,3.,字典,4.,集合,5.,组合数据类型的高级特性,5.,组合数据类型的高级特性,5.1,切片,La:b,表示从索引,a,开始取,直到索引,b,为止,但不包括索引,b,。,取,前,3,个元素,用一行代码就可以完成切片。,从索引,1,开始,取出,2,个元素,:,支持倒数切片,。,L,-1,取倒数第一个元素,L=Michael,Sarah,Tracy,Bob,Jack,L0:3,Michael,Sarah,Tracy,L1:3,Sarah,Tracy,5.,组合数据类型的高级特性,5.1,切片,简单应用,切片操作十分有用。我们先创建一个,099,的数列,。,L=list(range(100),L,0,1,2,3,99,L-10:,90,91,92,93,94,95,96,97,98,99,可以通过切片轻松取出某一段数列。比如前,10,个数:,L:10,0,1,2,3,4,5,6,7,8,9,后,10,个数:,5.,组合数据类型的高级特性,5.1,切片,简单应用,前,1120,个数:,L10:20,10,11,12,13,14,15,16,17,18,19,L:5,0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,前,10,个数,每两个取一个:,L:10:2,0,2,4,6,8,所有数,每,5,个取一个:,5.,组合数据类型的高级特性,5.1,切片,tuple,切片、字符串切片,tuple,也是一种,list,,唯一区别是,tuple,不可变。因此,,tuple,也可以用切片操作,只是操作的结果仍是,tuple,。,(0,1,2,3,4,5):3,(0,1,2),字符串,xxx,也可以看成是一种,list,,每个元素就是一个字符。因此,字符串也可以用切片操作,只是操作结果仍是字符串。,ABCDEFG:3,ABC,ABCDEFG:2,ACEG,5.,组合数据类型的高级特性,5.2,迭代,可迭代对象的迭代,列表这种数据类型有下标,但很多其他数据类型是没有下标的,但是,只要是可迭代对象,无论有无下标,都可以迭代。,5.,组合数据类型的高级特性,5.2,迭代,可迭代对象的迭代,字典的,迭代,d=a:1,b:2,c:3,for key in d:,print(key),a,c,b,由于字典是无序的,因此迭代出的结果顺序可能与上述结果不一样。,默认情况下,,dict,迭代的是,key,。如果要迭代,value,,可以用,for value in d.values(),,如果要同时迭代,key,和,value,,可以用,for k,v in d.items(),。,5.,组合数据类型的高级特性,5.2,迭代,可迭代对象的迭代,集合的迭代,s=set(1,2,3,4),s,1,2,3,4,for x in s:,print(x),1,2,3,4,5.,组合数据类型的高级特性,5.2,迭代,可迭代对象的迭代,字符串的迭代,for ch in ABC:,print(ch),A,B,C,所以,当我们使用,for,循环时,只要作用于一个可迭代对象,,for,循环就可以正常运行,而我们不用太关心该对象究竟是,list,还是其他数据类型。,5.,组合数据类型的高级特性,5.2,迭代,Iterable,类型,对于,一个对象,通常是通过,collections,模块的,Iterable,类型判断该对象是否是一个可迭代的对象,如:,from collections import Iterable,isinstance(abc,Iterable#str,是否可迭代,True,isinstance(1,2,3,Iterable)#list,是否可迭代,True,isinstance(123,Iterable)#,整数是否可迭代,False,5.,组合数据类型的高级特性,5.2,迭代,列表实现下标循环,如果要对,list,实现类似,Java,那样的下标循环,要怎么办呢?,Python,内置的,enumerate,函数可以把一个,list,变成索引元素对,这样就可以在,for,循环中同时迭代索引和元素本身。,for i,value in enumerate(A,B,C):,print(i,value),0 A,1 B,2 C,5.,组合数据类型的高级特性,5.3,列表,生成,式,一层,循环,list(range(1,11),1,2,3,4,5,6,7,8,9,10,要生成,list 1,2,3,4,5,6,7,8,9,10,,可以用,list(range(1,11),:,L=,for x in range(1,11):,L.append(x*x),L,1,4,9,16,25,36,49,64,81,100,但如果要生成,11,22,33,1010,,可使用下列语句。,5.,组合数据类型的高级特性,5.3,列表,生成,式,一层,循环,x*x for x in range(1,11),1,4,9,16,25,36,49,64,81,100,利用列表生成式可以用一行语句代替循环生成上面的,list,。,x*x for x in range(1,11)if x%2=0,4,16,36,64,100,for,循环后面还可以加上,if,判断,这样我们就可以筛选出仅偶数的平方。,5.,组合数据类型的高级特性,5.3,列表,生成,式,一层,循环,L=Hello,World,IBM,Apple,s.lower()for s in L,hello,world,ibm,apple,另外,也可把一个,list,中所有的字符串变成小写:,5.,组合数据类型的高级特性,5.3,列表,生成,式,两层循环,m+n for m in ABC for n in XYZ,AX,AY,AZ,BX,BY,BZ,CX,CY,CZ,下面看一个两层循环的例子。,上例,同时执行,for m in ABC,循环和,for n in XYZ,循环,然后再执行,m,+,n,。,5.,组合数据类型的高级特性,5.4,生成器,通过列表生成式,我们可以直接创建一个列表。但由于计算机内存有限,当生成一个列表时,由于受到计算机内存容量的限制,我们需要使用合理的方法生成列表。例如,对于一个包含百万数目的列表,无法直接创建该列表。如果该列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?答案是肯定的,而这样做的好处是不必创建完整的,list,,可以节省大量的空间。,在,Python,中,这种一边循环一边计算的机制,称为生成器(,generator,)。,5.,组合数据类型的高级特性,5.4,生成器,简单,生成器,要,创建一个,generator,,有很多种方法。,第一,种方法很简单,只要把一个列表生成式的,改成,(),,就创建了一个,generator,。,L=x*x for x in range(10),L,0,1,4,9,16,25,36,49,64,81,g=(x*x for x in range(10),g,at 0 x1022ef630,5.,组合数据类型的高级特性,5.4,生成器,带,yield,语句的生成器,如果,一个函数定义中包含,yield,关键字,那么这个函数就不再是一个普通函数,而是一个,generator,。,这里,最难理解的就是,generator,和函数的执行流程不一样。函数是顺序执行,遇到,return,语句或者最后一行函数语句就返回。而,generator,函数,在每次调用,next(),的时候执行,遇到,yield,语句返回,再次执行时从上次返回的,yield,语句处继续执行。,5.,组合数据类型的高级特性,5.4,生成器,递归生成器,def flatten(nested):,try:,#,不要迭代类似字符串的对象,try:nested+,except TypeError:pass,else:raise TypeError,for sublist in nested:,for element in flatten(sublist):,yield element,except TypeError:,yield,nested,如果要处理任意层的嵌套怎么办?每层嵌套需要增加一个,for,循环,但不知道有几层嵌套,所以必须把解决方案变得更灵活。,5.,组合数据类型的高级特性,5.4,生成器,生成器方法,外部作用域访问生成器的,send,方法,就像访问,next,方法一样,只不过前者使用一个参数(要发送的“消息”,任意对象)。,在内部则挂起生成器,,yield,现在作为表达式而不是语句,使用,换句话说,当生成器重新运行的时候,,yield,方法返回一个值,也就是外部通过,send,方法发送的值。如果,next,方法被使用,那么,yield,方法返回,None,。,throw,方法(使用异常类型调用,还有可选的值以及回溯对象)用于在生成器内引发一个异常(在,yield,表达式中)。,close,方法(调用时不用参数)用于停止生成器。,5.,组合数据类型的高级特性,5.4,生成器,模拟生成器,下面介绍如何使用普通的函数模拟生成器,。,def flatten(nested):,result=,try:,try:nested+,except TypeError:pass,else:raise TypeError,for sublist in nested:,for element in flatten(sublist):,result.append(element),except TypeError:,result.append(nested),return
展开阅读全文