python程序設(shè)計(jì) 課件 第6章 序列與迭代_第1頁(yè)
python程序設(shè)計(jì) 課件 第6章 序列與迭代_第2頁(yè)
python程序設(shè)計(jì) 課件 第6章 序列與迭代_第3頁(yè)
python程序設(shè)計(jì) 課件 第6章 序列與迭代_第4頁(yè)
python程序設(shè)計(jì) 課件 第6章 序列與迭代_第5頁(yè)
已閱讀5頁(yè),還剩79頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第6章序列與迭代Python程序設(shè)計(jì)第6章序列與迭代Python的序列類型包括列表、元組、字符串、文件等,存取這些抽象類型時(shí),核心的概念就是迭代,一個(gè)接著一個(gè)地逐一操作。這種形式的數(shù)據(jù)不勝枚舉,所以Python提供了充分的支持。以列表為中心,圍繞著許多相關(guān)類型、內(nèi)置函數(shù)、方法、列表生成式等,以方便我們?cè)诔绦蚶锾幚硇蛄行问降臄?shù)據(jù)。事實(shí)上,順序、條件判斷、再加上迭代(重復(fù))的執(zhí)行形式,就組成了基本的程序流程。類型與對(duì)象1迭代的概念4抽象數(shù)據(jù)類型2元素的訪問(wèn)3列表生成式5目錄6.1類型與對(duì)象類型即對(duì)象命名空間6.1

類型與對(duì)象我們已經(jīng)熟悉類型、對(duì)象、名稱(標(biāo)識(shí)符)之間的關(guān)系了,也學(xué)會(huì)了不少類型,包括整數(shù)(int)、浮點(diǎn)數(shù)(?oat)、列表(list)、字符串(str)等等,甚至函數(shù)(function)、模塊(module)也都是類型。例如:>>>a=22;b=4+5j;c='hi';d=(169,44)>>>e=['Amy',a,d]>>>defsq(x):returnx*x...>>>importmath這里的a、b、c、d、e、sq、math都是名稱,分別指向某種對(duì)象,而對(duì)象必定屬于某種類型,規(guī)定了該對(duì)象的接口與用法;我們可用內(nèi)置函數(shù)type查出某對(duì)象的類型,type()會(huì)顯示<class'XXX'>。>>>type(a);type(c);type(e) #查詢對(duì)象的類型<class'int'><class'str'><class'list'>>>>type(sq);type(math) #模塊與函數(shù)也是對(duì)象,<class'function'>#也有類型<class'module'>6.1

類型與對(duì)象6.1.1類型即對(duì)象所謂“類型(type)”在程序里也是以對(duì)象形式存在的,使用type()得到代表類型的對(duì)象后,可以比較判斷兩個(gè)對(duì)象的類型是否相同;有些基本類型直接輸入其名稱便可得到代表該類型的對(duì)象,有些類型則被放在某個(gè)模塊內(nèi)。>>>it=type(a) #類型是對(duì)象,也能命名>>>it<class'int'>>>>type(a)istype(99) #比較類型是否為同一個(gè)True>>>int,float,complex #基本的類型,直接取用(<type'int'>,<type'float'>,<type'complex’>)>>>tuple,list,str(<class'tuple'>,<class'list'>,<class'str'>)>>>type(e)islist #直接取用類型作判斷True>>>importtypes #有些類型被放在模塊內(nèi)>>>type(sq)istypes.FunctionTypeTrue>>>type(math)istypes.ModuleTypeTrue6.1.1類型即對(duì)象6.1.1類型即對(duì)象整數(shù)對(duì)象的類型是int,類型既然是對(duì)象,那么它也有類型,類型對(duì)象的類型是type。>>>a=3 #名稱a指向int對(duì)象,值為3>>>type(a) #其類型是int<class'int'>>>>at=type(a)#名稱at指向type對(duì)象>>>type(at) #其類型是type<class'type'>表5-1列出了Python的部分類型。6.1.1類型即對(duì)象表6-1代表類型的對(duì)象位于何處(部分)6.1.1類型即對(duì)象每個(gè)對(duì)象的類型各有其獨(dú)特的性質(zhì),例如int對(duì)象不可變,list對(duì)象是可變的容器,函數(shù)對(duì)象可被調(diào)用。在需要區(qū)別的時(shí)候,我們會(huì)稱呼某類型建立的對(duì)象為“實(shí)體”,以避免混淆。使用內(nèi)置函數(shù)instance可判斷對(duì)象是否為某類型的實(shí)體。>>>callable(sq),callable(math)#sq是函數(shù),可被調(diào)用(True,False)>>>callable(list),callable(int) #list、int不僅是類型的名稱,也可被調(diào)用(True,True)>>>isinstance(sq,types.FunctionType)#sq是函數(shù)類型的實(shí)體True>>>isinstance(d,tuple) #d是tuple類型的實(shí)體True6.1.2命名空間名稱會(huì)指向?qū)ο?,命名空間是名稱存在的地方,模塊、函數(shù)、類型、實(shí)體(對(duì)象)都具備命名空間的功能。importmathpi=math.pic=complex(3,4)defcircle(r)area=pi*r*rreturnarea在上述代碼中,全局范圍的命名空間里含有名稱math、pi、circle,其中math是個(gè)模塊、pi與c都是對(duì)象,都具有命名空間的功能,例如math里的sqrt、?oor、trunc都指向函數(shù),c對(duì)象里面的real與imag則指向浮點(diǎn)數(shù)。6.1.2命名空間函數(shù)具有命名空間的功能,但上述程序只“定義”了函數(shù)circle但尚未調(diào)用,也就是說(shuō),此時(shí)尚未產(chǎn)生circle的局部命名空間,更別提名稱r是否存在了。調(diào)用函數(shù)才會(huì)建立出局部(函數(shù))范圍的命名空間,里面會(huì)放著r、area。一旦函數(shù)結(jié)束(返回),該局部(函數(shù))范圍的命名空間也會(huì)消失,這里說(shuō)的是“名稱”消失了,所以在函數(shù)之外將無(wú)法使用函數(shù)內(nèi)的名稱area,不過(guò)函數(shù)返回的對(duì)象若還有名稱指向它,就仍會(huì)繼續(xù)存活。當(dāng)在程序里取用某名稱時(shí),如果位于函數(shù)內(nèi),會(huì)先到局部(函數(shù))范圍命名空間尋找,找不到會(huì)去全局范圍命名空間尋找,若再找不到會(huì)去存放內(nèi)置名稱命名空間(由模塊__builtins__提供)尋找。在局部與全局之間還有一個(gè)“外圍函數(shù)”的范圍。

搜尋名稱時(shí)的順序規(guī)則5.2抽象數(shù)據(jù)類型序列的概念迭代器共同接口6.2

抽象數(shù)據(jù)類型前面介紹類型與對(duì)象時(shí),一個(gè)對(duì)象看似都只有一個(gè)類型,例如3是int,[0,1,2]是list,但實(shí)際情況會(huì)更復(fù)雜。例如list、tuple、str都是序列類型,那么“序列”的類型在哪里呢?6.2.1序列的概念序列是個(gè)抽象類型,list、tuple、str都是實(shí)際類型,可產(chǎn)生出對(duì)象,但我們不能用序列類型產(chǎn)生對(duì)象,只能說(shuō)類型為list(或tuple、str)的對(duì)象符合序列定義的操作接口。某些類型擁有相同的接口,例如list擁有“長(zhǎng)度”的概念,而tuple、str也有,但int、?oat沒(méi)有。此時(shí)可把這部分的接口提出來(lái),放在抽象類型里,讓list、tuple、str遵循并符合此抽象類型的描述。序列相關(guān)的抽象類型層級(jí)6.2.1序列的概念“長(zhǎng)度或大小”的觀念由抽象類型Sized定義,所以符合此接口的類型對(duì)象必須含有方法__len__,從其名稱前后有兩個(gè)下劃線便可猜想,這是個(gè)具有特定意義、預(yù)先規(guī)定好名稱的方法,會(huì)被運(yùn)算符或內(nèi)置函數(shù)取用。而抽象類型Container定義了“某東西是否在里面”的觀念,由__contains__負(fù)責(zé),Sequence(序列)抽象類型“繼承”了Sized與Container,也就是說(shuō)符合其定義的接口,更進(jìn)一步定義了“取出元素”(__getitem__)、“某元素的索引”(index)等接口,而MutableSequence(可變序列)抽象類型又再以Sequence為基礎(chǔ)、加入可修改內(nèi)容的接口,諸如“移除”、“附加”、等等。這些抽象類型被放在模塊collections.abc里,可以使用內(nèi)置函數(shù)isinstance得知實(shí)體對(duì)象是否符合某類型(與抽象類型),而內(nèi)置函數(shù)issubclass可得知類型與類型之間的繼承關(guān)系(包括抽象類型)。6.2.2迭代器再來(lái)看可迭代項(xiàng)(Iterable)與迭代器(Iterator)。抽象類型Iterable定義了“建立Iterator”的接口,而Iterator定義了“逐步取出下一個(gè)元素”的接口,下面是個(gè)簡(jiǎn)單的實(shí)例。>>>li=[30,41,52] #list對(duì)象,也是可迭代項(xiàng)>>>lit=iter(li) #以內(nèi)置函數(shù)iter取得迭代器>>>lit #名稱lit指向這個(gè)迭代器<list_iteratorobjectat0x00BD6C90>>>>next(lit) #以內(nèi)置函數(shù)next可取得下一個(gè)元素30>>>next(lit)41>>>next(lit)52>>>next(lit) #沒(méi)有下一個(gè)了,發(fā)生錯(cuò)誤Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>StopIteration6.2.2迭代器6.2.3共同接口Python運(yùn)用各種類型(包括抽象類型)來(lái)規(guī)范對(duì)象的接口,根據(jù)類型定義出一套存取方式,list、tuple、str都符合序列抽象類型,list還符合可變序列抽象類型。表5-2列出這些類型都支持的操作動(dòng)作,表5-3列出可變的操作動(dòng)作。除了list、tuple、str之外,還有其他類型繼承自序列抽象類型。字符串str除了這里列出的操作動(dòng)作,還有很多跟“文本”相關(guān)的方法。在表5-2里,s與t代表某一種序列類型的實(shí)體對(duì)象,i、j、k則都是整數(shù)。6.2.3共同接口表6-2序列類型共同的操作動(dòng)作6.2.3共同接口在表6-3里,s代表可變序列類型的實(shí)體對(duì)象,t是可迭代項(xiàng)。表6-3可變序列類型共同的操作動(dòng)作索引、切片序列比較運(yùn)算符“+”與“*”序列類型的方法淺復(fù)制與深復(fù)制6.3元素的訪問(wèn)6.3

元素的訪問(wèn)序列類型是一種容器(數(shù)據(jù)結(jié)構(gòu)),里面的內(nèi)容稱為元素,它們的存取方式介紹如下。6.3.1序列元素索引以方括號(hào)“[]”的索引方式來(lái)指定想存取的元素,索引值從0開(kāi)始計(jì)數(shù),所以長(zhǎng)度為n的序列,有效合法的索引值會(huì)是0到n-1。>>>li=[30,41,52,63,74,85]>>>li[0] #取得索引值0之處的對(duì)象30>>>li[5],li[len(li)-1] #以內(nèi)置函數(shù)len得知長(zhǎng)度(85,85)>>>li[99] #超過(guò)了,發(fā)生錯(cuò)誤Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>IndexError:listindexoutofrange#索引錯(cuò)誤:列表索引值超過(guò)界限>>>s='hellopython' #字符串也能使用索引>>>s[0],s[6]('h','p')>>>s[0],s[6],s[len(s)-1]('h','p','n')6.3.1序列元素索引6.3.1序列元素索引任何序列類型,例如list、tuple、str等都可以使用索引存取方式。索引值也可以是負(fù)數(shù),如果是-i(假設(shè)i為正數(shù)),會(huì)被當(dāng)作“長(zhǎng)度-i”。假設(shè)序列對(duì)象s長(zhǎng)度是n,那么s[-i]將等同于s[len(s)-i]。負(fù)索引值從-1(最后的元素)到-n(最前面的元素)。>>>li=[30,41,52,63,74,85] #長(zhǎng)度是6>>>li[-1],li[len(li)-1] #此處[-1]等同于[6-1](85,85) #以[-1]存取最后的元素,比len()方便>>>li[-2],li[-5],li[-6],li[-len(li)](74,41,30,30)>>>li[0],li[-0] #注意,-0還是0,不是6–0(30,30)>>>li[-7] #超過(guò)了,發(fā)生錯(cuò)誤Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>IndexError:listindexoutofrange6.3.1序列元素索引6.3.1序列元素索引如果是可變序列類型,例如list,就能以賦值語(yǔ)句修改其內(nèi)容,即讓該索引值轉(zhuǎn)而指向新對(duì)象。>>>li=[30,41,52,63,74,85]>>>li[0]='Amy' #修改第0個(gè)>>>li[len(li)-1]=('a','b','c')>>>li['Amy',41,52,63,74,('a','b','c')]>>>li2=['a','b','c']>>>li[-1]=li2 #指向新對(duì)象,是個(gè)列表>>>li['Amy',41,52,63,74,['a','b','c']]>>>li2[0]='abc' #修改li2>>>li #li[-1]也變了['Amy',41,52,63,74,['abc','b','c']]>>>li[-1]isli2 #因?yàn)閮烧叨贾赶蛲粋€(gè)對(duì)象True6.3.1序列元素索引6.3.1序列元素索引如果是可變序列類型,例如list,就能以del語(yǔ)句刪除元素。>>>li=[30,41,52,63,74,85]>>>delli[0] #刪除第0個(gè)>>>li[41,52,63,74,85]>>>delli[-1] #刪除最后一個(gè)>>>li[41,52,63,74]“刪除元素”的意思是移除掉該列表的某索引值以及指向?qū)ο蟮慕壎P(guān)系。6.3.2序列切片除了索引,Python還提供切片方式來(lái)存取序列類型,基本語(yǔ)法是s[i:j],i代表起始索引值,j代表結(jié)束索引值(不包含),切片的結(jié)果是新的序列對(duì)象。>>>li=[30,41,52,63,74,85]>>>li[0:3] #從0到3(不包含)[30,41,52] #新的列表對(duì)象>>>li[2:] #沒(méi)指定j,缺省為長(zhǎng)度len(li)[52,63,74,85]>>>li[:4] #沒(méi)指定i,缺省為0[30,41,52,63]>>>li[5:3] #i大于j[] #得到空列表>>>li[99:3] #i若大于長(zhǎng)度,會(huì)被視為長(zhǎng)度[]>>>li[3:99] #j若大于長(zhǎng)度,會(huì)被視為長(zhǎng)度[63,74,85]>>>li[:] #i與j都沒(méi)指定,等同于[0:len(li)],[30,41,52,63,74,85] #等同于復(fù)制li>>>first,rest=li[0],li[1:] #拿出第0個(gè)與其他>>>first,rest(30,[41,52,63,74,85])>>>first,*rest=li #“星號(hào)序列指派”拿出第0個(gè)與其他6.3.2序列切片6.3.2序列切片切片也能使用負(fù)數(shù),規(guī)則與索引相同。>>>li=[30,41,52,63,74,85] #長(zhǎng)度是6>>>li[-4:-2] #等同于li[len(li)-4:len(li)-2][52,63] #也就是li[2:4]>>>li[-2:] #沒(méi)指定j,缺省為長(zhǎng)度len(li)[74,85]>>>li[:-3] #沒(méi)指定i,缺省為0[30,41,52]>>>rest,last=li[:-1],li[-1] #拿出最后一個(gè)與其他>>>rest,last([30,41,52,63,74],85)>>>*rest,last=li #“星號(hào)序列指派”拿出最后一個(gè)與其他6.3.2序列切片以上切片的索引值每次跳1,例如li[2:5]會(huì)取出2、3、4,但也能自行指定每次跳幾個(gè)元素,語(yǔ)法是s[i:j:k],其中k可正可負(fù),不可為0。>>>li=[30,41,52,63,74,85] #長(zhǎng)度是6>>>li[1:5:2] #索引值1、3[41,63]>>>li[-1:1:-2] #k為負(fù)數(shù),從尾巴往開(kāi)頭跳,[85,63] #索引值5、3>>>li[::-1] #得到逆轉(zhuǎn)后的列表[85,74,63,52,41,30]6.3.2序列切片>>>li[::-2] #從尾部往開(kāi)頭跳,一次跳兩個(gè)[85,63,41]>>>a,b,c=li[1:4] #拿出三個(gè)元素,指派給名稱a、b、c>>>a,b,c(41,52,63)>>>a,*b=li[1::2] #星號(hào)序列指派,3.x版才有>>>a #第一個(gè)指派給a41>>>b #其余的放進(jìn)列表指派給b[63,85]6.3.2序列切片如果是可變序列類型,例如list,那么就能以指派語(yǔ)句(assignment)修改內(nèi)容,就是把切片指定的地方置換成賦值語(yǔ)句右邊的內(nèi)容。>>>li=[30,41,52,63,74,85]>>>li[0:2]='a','b' #賦值語(yǔ)句左邊是列表切片,>>>li #右邊可以是任何序列類型['a','b',52,63,74,85]>>>li[1:3]='x','y','z' #右邊數(shù)量比左邊多,>>>li #會(huì)把切片指定的地方置換成右邊的內(nèi)容['a','x','y','z',63,74,85]>>>li[0:2]=9999 #右邊必須是個(gè)可迭代項(xiàng)Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>TypeError:canonlyassignaniterable6.3.2序列切片>>>li[0:2]=[] #若右邊是空的,>>>li #等同于刪除左邊切片指定的元素['y','z',63,74,85]>>>li[1:-1]=[] #留下前后兩個(gè),中間的全部刪除>>>li['y',85]6.3.2序列切片如果是可變序列類型,例如list,那么可以用del語(yǔ)句刪除元素。>>>li=[30,41,52,63,74,85]>>>delli[0:3] #刪除索引值0、1、2的元素>>>li[63,74,85]>>>li=[30,41,52,63,74,85]>>>delli[-1:-3] #想要?jiǎng)h除最后兩個(gè)元素>>>li#錯(cuò)了,[-1:-3]會(huì)是[][30,41,52,63,74,85]>>>delli[-3:-1]#[-3:-1]才是最后兩個(gè)元素6.3.2序列切片>>>li[30,41,52,85]>>>delli[::2] #刪除奇數(shù)位置的元素>>>li[41,85]>>>delli[:] #刪除所有元素>>>li #變成空列表了[]>>>delli #刪除名稱li、連帶移除與指向?qū)ο蟮慕壎P(guān)系>>>liTraceback(mostrecentcalllast):File"<stdin>",line1,in<module>NameError:name'li'isnotdefined6.3.2序列切片6.3.3對(duì)象的比較以運(yùn)算符“is、isnot”來(lái)判斷是否為同一個(gè)對(duì)象,以運(yùn)算符“==、!=“來(lái)比較兩個(gè)對(duì)象內(nèi)容是否相同。>>>li=[3,4,5,6]>>>li2=li[:] #復(fù)制t,新的對(duì)象指派給名稱t2>>>li==li2,liisli2 #t與t2內(nèi)容相同,但非同一對(duì)象(True,False)運(yùn)算符“xins”可檢查序列s里是否有個(gè)元素與x相等,“notin”則反過(guò)來(lái)。>>>li=[['a','b'],('x',9,(3,4)),5,6]>>>5inli#有True>>>3notinli #沒(méi)有True>>>not3inli #等同于“not(3inli)”True#因?yàn)檫\(yùn)算符in優(yōu)先順序較高>>>['a','b']inli #['a','b']是個(gè)listTrue6.3.3對(duì)象的比較>>>('a','b')inli #內(nèi)容看似雷同,但這是個(gè)tupleFalse>>>['a','b']==('a','b')#判斷規(guī)則就是“==”False>>>(3,4)inli #li并沒(méi)有(3,4)False>>>('x',9,(3,4))inliTrue6.3.3對(duì)象的比較在序列類型中,“+”代表連接,把兩個(gè)序列對(duì)象連接在一起,建立新的序列。>>>li=[0,1,2];t=(3,4,5,6);s='Hello'>>>li+[30,41,52] #連接兩個(gè)列表[0,1,2,30,41,52]>>>t+('a','b','c') #連接兩個(gè)tuple(3,4,5,6,'a','b','c')>>>s+'Python,'+'howareyou?' #連接好幾個(gè)字符串'helloPython,howareyou?'6.3.4運(yùn)算符“+”與“*”>>>li+t#連接不同類型,出錯(cuò)Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>TypeError:canonlyconcatenatelist(not"tuple")tolist>>>li+list(t) #內(nèi)置函數(shù)list轉(zhuǎn)換類型[0,1,2,3,4,5,6]>>>tuple(li)+t #內(nèi)置函數(shù)tuple轉(zhuǎn)換類型(0,1,2,3,4,5,6)6.3.4運(yùn)算符“+”與“*”6.3.4運(yùn)算符“+”與“*”由于會(huì)產(chǎn)生新的對(duì)象,若需要頻繁使用“+”,或許會(huì)有效能低下的問(wèn)題,可考慮改用可變對(duì)象與別的方法來(lái)達(dá)成同樣的功能。“*”代表復(fù)制(或稱拷貝),須注意別名現(xiàn)象。對(duì)于增強(qiáng)型賦值語(yǔ)句“+=、*=”,若是不可變對(duì)象,那就一定是由右邊表達(dá)式建立新對(duì)象、再指派給左邊名稱,若是可變對(duì)象,則會(huì)是原地修改。>>>li=li2=[0,1,2] #可變>>>li+=[98,99] #原地修改>>>li==li2,liisli2 #li與li2是同一個(gè)列表對(duì)象(True,True)>>>t=t2=(3,4,5) #不可變>>>t+=('a','b') #t指向新的tuple對(duì)象>>>t==t2,tist2(False,False)6.3.4運(yùn)算符“+”與“*”6.3.5序列類型的方法除了運(yùn)算符與內(nèi)置函數(shù),序列類型也擁有許多方法。先介紹不可變的方法index與count。給定參數(shù)后,s.index(x)可找出x在s里第一次出現(xiàn)的索引值,而s.count(x)則返回在s里x出現(xiàn)的次數(shù)。>>>li=[3,'a',3,'hi',7,(10,7),3]>>>li.index(3) #找出'a'的索引值0>>>li.index(3,1) #也可以指定從哪個(gè)索引值開(kāi)始找2>>>li.index(3,3,len(li)) #也可以再指定找到哪個(gè)索引值(不含)為止6>>>li.count(3) #計(jì)算3出現(xiàn)的次數(shù)3>>>li.count(4) #4在li里出現(xiàn)0次0>>>li.index(4) #沒(méi)這個(gè)東西,會(huì)發(fā)生錯(cuò)誤Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>ValueError:4isnotinlist #值錯(cuò)誤:4不在列表里6.3.5序列類型的方法6.3.5序列類型的方法若是可變的序列類型,例如list,還有許多更簡(jiǎn)便的方法可用,這些方法會(huì)直接操作修改list對(duì)象,不會(huì)建立新的list對(duì)象。>>>li=[]>>>li.append(3)#append會(huì)把參數(shù)當(dāng)作元素加入>>>li.append(('a','b'))#參數(shù)是個(gè)tuple>>>li[3,('a','b')]>>>li.extend(('a','b'))#extend是把參數(shù)的內(nèi)容當(dāng)作元素加入>>>li[3,('a','b'),'a','b']6.3.5序列類型的方法>>>li.insert(2,'XXX') #在索引值2的地方插入'XXX'>>>li[3,('a','b'),'XXX','a','b']>>>li.remove('XXX')#刪除等于'XXX'的元素,只會(huì)刪除靠前的一個(gè)>>>li[3,('a','b'),'a','b']>>>li.pop(2)#拿出索引值2的元素,并移除'a'>>>li.pop()#拿出最后一個(gè)元素,并移除'b'6.3.5序列類型的方法>>>li.reverse()#原地逆轉(zhuǎn)li里的元素[('a','b'),3]>>>li=[9,1,4,6,2]>>>li.sort()#原地排序>>>li[1,2,4,6,9]>>>li2=li.copy()#淺復(fù)制>>>li.clear()#清空,等同于delli[:]>>>li[]6.3.5序列類型的方法6.3.6淺復(fù)制與深復(fù)制深復(fù)制(拷貝)和淺復(fù)制(拷貝)只針對(duì)Object和Array這樣的引用數(shù)據(jù)類型,大致如圖所示。淺復(fù)制只賦值指向某個(gè)對(duì)象的指針,而不賦值對(duì)象本身,新舊對(duì)象還是共享同一塊內(nèi)存。但深復(fù)制會(huì)另外創(chuàng)造一個(gè)一模一樣的對(duì)象,新對(duì)象跟原對(duì)象不共享內(nèi)存,修改新對(duì)象不會(huì)改到原對(duì)象。深復(fù)制與淺復(fù)制6.4

迭代的概念6.4

迭代的概念迭代是一種抽象概念,意思就是“一個(gè)接著一個(gè)處理”或“從容器中一個(gè)接著一個(gè)拿出元素”,當(dāng)你使用循環(huán)來(lái)處理一組項(xiàng)目時(shí),使用的就是迭代。所謂協(xié)議指的是一套溝通標(biāo)準(zhǔn),交流雙方都必須遵循這套標(biāo)準(zhǔn),才能正常對(duì)話,迭代協(xié)議也是這個(gè)意思,一方提供東西,另一方則接收東西,雙方采用同一套標(biāo)準(zhǔn)作法。以下面程序代碼為例,會(huì)逐一輸出list里的元素。li=[30,41,52]forxinli: #以for循環(huán)迭代列表

print(x)此例中的list對(duì)象與for循環(huán)分別代表迭代協(xié)議中的兩方,list對(duì)象以符合迭代協(xié)議的方式提供東西,而for循環(huán)也透過(guò)符合迭代協(xié)議的接口接收并處理。6.4

迭代的概念與迭代協(xié)定相關(guān)的接口有兩個(gè):Iterable與Iterator,Iterable(可迭代項(xiàng))的__iter__方法(對(duì)應(yīng)到內(nèi)置函數(shù)iter)會(huì)返回迭代器,而Iterator(迭代器)的__next__方法(對(duì)應(yīng)到內(nèi)置函數(shù)next),每次調(diào)用會(huì)返回下一個(gè)元素,直到盡頭,到時(shí)會(huì)發(fā)出錯(cuò)誤告知調(diào)用方。例如,list類型繼承自Sequence抽象類型,而Sequence也繼承了Iteratable抽象類型,所以list對(duì)象也是可迭代項(xiàng),調(diào)用方法iter的話便可得到能夠迭代list內(nèi)容元素的迭代器。>>>li=[30,41,52] #list對(duì)象,也是可迭代項(xiàng)>>>itb=iter(li) #得到迭代器>>>itb #沒(méi)錯(cuò),是個(gè)能迭代list的迭代器<list_iteratorobjectat0x00BED810>>>>type(itb) #它的類型是list_iterator<class'list_iterator'>>>>importcollections.abc>>>issubclass(type(itb),collections.abc.Iterator)True #list_iterator符合Iterator接口6.4

迭代的概念>>>issubclass(list,collections.abc.Iterable)True #list符合Iterable接口>>>next(itb) #調(diào)用next可拿到下一個(gè)元素30>>>next(itb)41>>>next(itb)52>>>next(itb) #沒(méi)有了,發(fā)生錯(cuò)誤Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>StopIteration #異常StopIteration(停止迭代)6.4

迭代的概念6.4

迭代的概念當(dāng)?shù)骱谋M時(shí),若再調(diào)用next則會(huì)引發(fā)異常StopIteration,而調(diào)用方/接收方看到異常StopIteration的話,便會(huì)停止迭代?!境绦?qū)嵗?-1】以while循環(huán)模擬出for循環(huán)迭代列表。li=[30,41,52]itb=iter(li)whileTrue:try: #把會(huì)引發(fā)異常的程序代碼放在try里面

x=next(itb) #拿出下一個(gè)元素

print(x) #輸出

exceptStopIteration: #若有此異常

break #跳出while循環(huán)6.4

迭代的概念6.4

迭代的概念程序分析:上面程序代碼進(jìn)入循環(huán)后,首次調(diào)用next(itb)會(huì)拿到30,然后輸出,接著輸出41與52,之后再調(diào)用next(itb)時(shí)會(huì)引發(fā)異常StopIteration,因?yàn)樵摱纬绦虼a被包在try語(yǔ)句之內(nèi),所以程序流程會(huì)直接到后面的except子句,比對(duì)有無(wú)列出相同的異常,若有就進(jìn)入該except子句內(nèi)繼續(xù)執(zhí)行。此例會(huì)以break中斷循環(huán);若無(wú)就繼續(xù)跳到外層的調(diào)用方,更外一層的調(diào)用方是Python解釋器,而它的處理方式是終止程序。內(nèi)置函數(shù)sum可以算出序列對(duì)象的元素總和,但其實(shí)它能接受的參數(shù)不只是序列類型,也可以是可迭代項(xiàng),不過(guò)sum的參數(shù)內(nèi)容不能是字符串。下面,我們使用循環(huán)與迭代協(xié)議,編寫與序列類型相關(guān)的實(shí)例程序?!境绦?qū)嵗?-2】能對(duì)數(shù)字求和、連接字符串的sum。#my_sum.pydefmy_sum(iterable,start=0):result=startforxiniterable: #iterable應(yīng)是個(gè)可迭代項(xiàng)

result+=xreturnresult6.4

迭代的概念6.4

迭代的概念有了這個(gè)函數(shù),想連接字符串時(shí),可傳入含字符串的序列,例如“('a','b','def','g')”,作為參數(shù)iterable,至于參數(shù)start則可傳入空字符串“''”作為起始值。雖然內(nèi)置函數(shù)sum有“+”的功能,但并沒(méi)有“*”的功能。下面函數(shù)product可算出乘積,寫法大致相同。【程序?qū)嵗?-3】計(jì)算乘積。#product.pydefproduct(iterable,start=1):result=startforxiniterable: #程序代碼跟之前幾乎一樣

result*=x #只有start缺省值與此處不同

returnresult有了product,就可改寫階乘函數(shù),使之變得更簡(jiǎn)單。6.4

迭代的概念6.4

迭代的概念sum的功能是算求和,但有時(shí)需要的是“累加”,若有個(gè)列表[a,b,c,...],那么它的累加和是[a,a+b,a+b+c,...]。調(diào)用下面的函數(shù)cumulative_sum(range(10+1)),可得到[0,1,3,6,10,15,21,28,36,45,55]?!境绦?qū)嵗?-4】階乘。#my_factorial.pydefmy_factorial(n):returnproduct(range(2,n+1)) #2*3*4*...*n6.4

迭代的概念【程序?qū)嵗?-5】累加。#cumulative_sum.pydefcumulative_sum(iterable,start=0):result=[]acc=start #記錄上次的和

forxiniterable:acc+=x #加上這次的數(shù)值

result.append(acc) #放進(jìn)去

returnresult函數(shù)unique可挑出至少出現(xiàn)過(guò)一次的元素,等同于拿掉重復(fù)的元素,例如unique([1,2,1,3,2,5,5,6,1])會(huì)得到[1,2,3,5,6]。6.4

迭代的概念6.5

列表生成式6.5

列表生成式列表是一種用途非常廣泛的數(shù)據(jù)結(jié)構(gòu)。列表可以放入任何類型的對(duì)象,例如能以列表表達(dá)班級(jí)成績(jī)、個(gè)人資料、溫度變化歷程等一連串的數(shù)據(jù),就算不是線性,列表也可以稍作變化,在列表內(nèi)放入列表,進(jìn)而可表達(dá)樹(shù)狀或其他形式的數(shù)據(jù)。元組(tuple)也具備上述特性,但list支持“可變”操作動(dòng)作,更有彈性。因?yàn)榱斜砣绱酥匾?,Python提供了稱為列表生成式的語(yǔ)法,其作用等同于結(jié)合for與if來(lái)建立新串列,在短短一行內(nèi)塞進(jìn)一大堆想做的事,可以讓程序代碼更簡(jiǎn)潔有力。其語(yǔ)法如下:[表達(dá)式for名稱in可迭代項(xiàng)][表達(dá)式for名稱in可迭代項(xiàng)if表達(dá)式]6.5

列表生成式例如,有個(gè)列表含有華氏溫度,想要轉(zhuǎn)換成攝氏溫度。華氏32度等于攝氏0度(冰點(diǎn)),華氏212度等于攝氏100度(沸點(diǎn))。如果使用for循環(huán)的話,程序代碼如下:defftoc(ft): #參數(shù)是含有華氏溫度的列表(或可迭代項(xiàng))

ct=[] #存儲(chǔ)轉(zhuǎn)換后的攝氏溫度

forxinft:ct.append((x-32)*5/9) #轉(zhuǎn)換

returnct但同樣的功能,只需要一行的列表生成式便可實(shí)現(xiàn),程序如下:【程序?qū)嵗?-6】華氏轉(zhuǎn)攝氏。#ft_to_ct.pyft=[32,212,10,55,78,110,178]#ft含有華氏溫度ct=[(x-32)*5/9forxinft] #轉(zhuǎn)成攝氏,并且建立新列

表,指派給ct6.5

列表生成式6.5

列表生成式首先,列表生成式是個(gè)表達(dá)式,以方括號(hào)“[]”包起來(lái),其結(jié)果會(huì)是個(gè)新列表;里面可分為前后兩部分,后面部分“forxinft”的意思其實(shí)就跟for循環(huán)的頭一樣,不斷地迭代ft列表(或可迭代項(xiàng))、把元素指派給名稱x,此例中x會(huì)指向代表華氏溫度的整數(shù)對(duì)象,然后由前面部分的表達(dá)式“(x-32)*5/9”轉(zhuǎn)換算出攝氏溫度,變成新列表的元素。如此,冗長(zhǎng)的程序代碼縮減為一行。以前使用for循環(huán)寫的程序,幾乎都可以換成列表生成式。再舉幾個(gè)簡(jiǎn)單例子:>>>li=[32,55,-68,10,-3,44,12,0] #含有整數(shù)的列表>>>[x*2forxinrange(10)] #兩倍[0,2,4,6,8,10,12,14,16,18]>>>li2=[abs(x)forxinli] #絕對(duì)值>>>li2[32,55,68,10,3,44,12,0]>>>frommathimportsqrt>>>scores=[11,23,64,100,91,60,55,44]#成績(jī)>>>[int(sqrt(x)*10)forxinscores] #調(diào)整成績(jī),開(kāi)根號(hào)再乘10[33,47,80,100,95,77,74,66]6.5

列表生成式6.5

列表生成式列表里也不一定是數(shù)字,可以是任何類型的對(duì)象。列表生成式的作用就是逐一處理元素后、再放進(jìn)新的列表。在下面的例子中,若已知原列表的內(nèi)容結(jié)構(gòu),便可運(yùn)用“序列指派”(第2章),把列表元素(是個(gè)tuple)的內(nèi)容一次指派給多個(gè)名稱。>>>li=[(30,41,65),(60,70,8

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論