《Python程序設(shè)計》課件5-數(shù)據(jù)結(jié)構(gòu)_第1頁
《Python程序設(shè)計》課件5-數(shù)據(jù)結(jié)構(gòu)_第2頁
《Python程序設(shè)計》課件5-數(shù)據(jù)結(jié)構(gòu)_第3頁
《Python程序設(shè)計》課件5-數(shù)據(jù)結(jié)構(gòu)_第4頁
《Python程序設(shè)計》課件5-數(shù)據(jù)結(jié)構(gòu)_第5頁
已閱讀5頁,還剩71頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

~1~第五章數(shù)據(jù)結(jié)構(gòu)目錄數(shù)據(jù)結(jié)構(gòu)的簡介Python內(nèi)置數(shù)據(jù)結(jié)構(gòu)列表元組字典集合編程實(shí)踐本章習(xí)題-2-5.1.數(shù)據(jù)結(jié)構(gòu)簡介數(shù)據(jù)的重要性在當(dāng)今數(shù)字化時代,數(shù)據(jù)無疑是構(gòu)成知識和信息的基石,它的重要性貫穿于我們的日常生活和各個工作領(lǐng)域。技術(shù)的飛速發(fā)展,尤其是在計算機(jī)和互聯(lián)網(wǎng)領(lǐng)域,極大地增強(qiáng)了我們收集、存儲和處理數(shù)據(jù)的能力。這種能力不僅改變了我們解決問題和做決策的方式,也重新定義了我們?nèi)绾卫斫夂突邮澜鐚τ诰幊毯蛙浖_發(fā)而言,能夠有效地組織和處理數(shù)據(jù)是至關(guān)重要的基礎(chǔ)技能。Python作為一門受歡迎的高級編程語言,因其提供的一系列強(qiáng)大而靈活的數(shù)據(jù)結(jié)構(gòu)而備受青睞。這些數(shù)據(jù)結(jié)構(gòu)使得Python成為了處理數(shù)據(jù)、開發(fā)高效和可維護(hù)程序的理想選擇-3-數(shù)據(jù)管理數(shù)據(jù)管理的關(guān)鍵性在于:提高效率:良好的數(shù)據(jù)組織方式能讓程序更迅速地訪問和處理數(shù)據(jù)。Python通過其內(nèi)置數(shù)據(jù)結(jié)構(gòu),比如列表和字典,為數(shù)據(jù)操作提供了高效的方法。這些結(jié)構(gòu)背后的優(yōu)化實(shí)現(xiàn)顯著提升了數(shù)據(jù)處理的速度和效率簡化數(shù)據(jù)操作:選擇合適的數(shù)據(jù)結(jié)構(gòu)可以極大簡化對復(fù)雜數(shù)據(jù)的操作。例如,Python的字典通過鍵值對的方式存儲數(shù)據(jù),使得數(shù)據(jù)的存儲、檢索和更新變得直觀易行適應(yīng)復(fù)雜數(shù)據(jù)處理:隨著應(yīng)用需求的增長,處理的數(shù)據(jù)結(jié)構(gòu)也隨之復(fù)雜化。Python的數(shù)據(jù)結(jié)構(gòu)庫支持從簡單的數(shù)據(jù)序列到復(fù)雜的樹和圖等非線性數(shù)據(jù)結(jié)構(gòu),以滿足不同的數(shù)據(jù)處理需求。這樣的支持確保Python程序能夠高效處理各種復(fù)雜度的數(shù)據(jù)場景4數(shù)據(jù)結(jié)構(gòu)的定義數(shù)據(jù)結(jié)構(gòu):是計算機(jī)科學(xué)中的一個核心概念,是指計算機(jī)中存儲、組織數(shù)據(jù)的方式數(shù)據(jù)結(jié)構(gòu)的兩大基本目的:一是為了使數(shù)據(jù)的存儲更為高效二是為了使數(shù)據(jù)的訪問和操作更加便捷、快速數(shù)據(jù)結(jié)構(gòu)可以是原始的,如整數(shù)、浮點(diǎn)數(shù)和字符等,也可以是復(fù)雜的,如列表、樹、圖等。每種數(shù)據(jù)結(jié)構(gòu)都有其特定的用途和操作方法,數(shù)據(jù)結(jié)構(gòu)的設(shè)計和選擇直接影響到程序的性能和效率列表(List):一種線性數(shù)據(jù)結(jié)構(gòu),能夠存儲一序列的元素。列表允許重復(fù)的元素,并支持按照元素的索引進(jìn)行訪問字典(Dictionary):一種基于鍵值對的數(shù)據(jù)結(jié)構(gòu),提供了快速檢索數(shù)據(jù)的能力。在Python中,字典是無序的集合,但從Python3.7起,字典被設(shè)計為保持插入順序樹(Tree):一種層次化的數(shù)據(jù)結(jié)構(gòu),由節(jié)點(diǎn)組成,每個節(jié)點(diǎn)包含一個父節(jié)點(diǎn)(除了根節(jié)點(diǎn)之外)和零個或多個子節(jié)點(diǎn)。樹結(jié)構(gòu)在表示層次關(guān)系或進(jìn)行快速檢索操作時非常有用圖(Graph):由節(jié)點(diǎn)(或稱為頂點(diǎn))和連接節(jié)點(diǎn)的邊組成的結(jié)構(gòu)。圖可以是有向的也可以是無向的,用于模擬實(shí)體間的復(fù)雜關(guān)系5數(shù)據(jù)結(jié)構(gòu)的分類數(shù)據(jù)結(jié)構(gòu)可以根據(jù)其組織數(shù)據(jù)的方式被分為兩大類:線性結(jié)構(gòu)和非線性結(jié)構(gòu)。這兩種結(jié)構(gòu)各有特點(diǎn),適用于解決不同類型的問題線性結(jié)構(gòu):線性結(jié)構(gòu)的數(shù)據(jù)元素之間是一對一的關(guān)系。在這種結(jié)構(gòu)中,除了第一個和最后一個數(shù)據(jù)元素之外,每個元素都有一個前驅(qū)和一個后繼。線性結(jié)構(gòu)的數(shù)據(jù)元素形成一個序列,最典型的線性結(jié)構(gòu)包括:數(shù)組:一種基礎(chǔ)且常用的數(shù)據(jù)結(jié)構(gòu),由固定大小的數(shù)據(jù)元素序列構(gòu)成,每個元素可以直接通過索引訪問鏈表:由一系列節(jié)點(diǎn)組成,每個節(jié)點(diǎn)包含數(shù)據(jù)部分和指向下一個節(jié)點(diǎn)的指針。鏈表可以是單向的也可以是雙向的棧(Stack):一種遵循后進(jìn)先出(LIFO)原則的集合。添加(推入)和移除(彈出)元素都發(fā)生在同一端隊列(Queue):一種遵循先進(jìn)先出(FIFO)原則的集合。元素從一端添加,從另一端移除線性結(jié)構(gòu)因其簡單和直觀,被廣泛應(yīng)用于各種程序和算法中6數(shù)據(jù)結(jié)構(gòu)的分類非線性結(jié)構(gòu)非線性結(jié)構(gòu)的數(shù)據(jù)元素之間可以是一對多或多對多的關(guān)系。這種結(jié)構(gòu)的數(shù)據(jù)元素以非順序的方式組織,典型的非線性結(jié)構(gòu)包括:樹(Tree):一種層次化的數(shù)據(jù)結(jié)構(gòu),由節(jié)點(diǎn)組成,每個節(jié)點(diǎn)包含一個父節(jié)點(diǎn)(除了根節(jié)點(diǎn)之外)和零個或多個子節(jié)點(diǎn)。二叉樹是樹的一種特殊形式,每個節(jié)點(diǎn)最多有兩個子節(jié)點(diǎn)圖(Graph):由節(jié)點(diǎn)(或稱頂點(diǎn))和連接節(jié)點(diǎn)的邊組成的結(jié)構(gòu)。圖可以是有向的也可以是無向的,用于表示實(shí)體間復(fù)雜的關(guān)系,如社交網(wǎng)絡(luò)、地圖等線性結(jié)構(gòu)和非線性結(jié)構(gòu)各自有著獨(dú)特的特點(diǎn)和適用場景線性結(jié)構(gòu)簡單直觀,適合表示數(shù)據(jù)的序列關(guān)系非線性結(jié)構(gòu)則更適合表示數(shù)據(jù)間復(fù)雜的層次關(guān)系或網(wǎng)絡(luò)關(guān)系在Python中,雖然直接支持的是更基本的線性數(shù)據(jù)結(jié)構(gòu),如列表、元組、字典和集合,但通過這些基本結(jié)構(gòu),我們可以構(gòu)建出復(fù)雜的非線性結(jié)構(gòu),如樹和圖,以解決更多樣化的問題。了解這些數(shù)據(jù)結(jié)構(gòu)的分類和基本概念,對于開發(fā)者選擇最適合解決特定問題的數(shù)據(jù)結(jié)構(gòu)至關(guān)重要75.2.Python內(nèi)置數(shù)據(jù)結(jié)構(gòu)Python作為一門強(qiáng)大的編程語言,提供了一系列高效、靈活的內(nèi)置數(shù)據(jù)結(jié)構(gòu),如列表(List)、元組(Tuple)、字典(Dictionary)和集合(Set)。這些數(shù)據(jù)結(jié)構(gòu)被設(shè)計來滿足日常編程中的各種需求,從簡單的數(shù)據(jù)集合到復(fù)雜的數(shù)據(jù)操作,都可以通過這些內(nèi)置數(shù)據(jù)結(jié)構(gòu)高效地完成Python的內(nèi)置數(shù)據(jù)結(jié)構(gòu):列表(List):一個有序的數(shù)據(jù)集合,可以存儲各種類型的數(shù)據(jù),并支持添加、刪除和搜索操作元組(Tuple):與列表類似,但是元組一旦創(chuàng)建便不能修改,適用于存儲不應(yīng)該改變的數(shù)據(jù)集合字典(Dictionary):基于鍵值對的數(shù)據(jù)結(jié)構(gòu),每個鍵都唯一對應(yīng)一個值,非常適合快速查找、添加和刪除操作集合(Set):一個無序且元素唯一的集合,適用于去重和執(zhí)行集合操作(如并集、交集)85.2.Python內(nèi)置數(shù)據(jù)結(jié)構(gòu)與自定義數(shù)據(jù)結(jié)構(gòu)相比,Python內(nèi)置數(shù)據(jù)結(jié)構(gòu)的優(yōu)勢:效率高:Python的內(nèi)置數(shù)據(jù)結(jié)構(gòu)是用C語言編寫的,這意味著它們非常高效,執(zhí)行速度快。在底層實(shí)現(xiàn)上進(jìn)行了大量優(yōu)化,可以顯著減少代碼的執(zhí)行時間易于使用:內(nèi)置數(shù)據(jù)結(jié)構(gòu)簡化了編程任務(wù),因為它們提供了許多方便的方法和操作。這些數(shù)據(jù)結(jié)構(gòu)的使用方法直觀易懂,大大降低了學(xué)習(xí)曲線,使得程序員可以更專注于解決問題,而不是在實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)上花費(fèi)太多時間可靠性強(qiáng):Python的內(nèi)置數(shù)據(jù)結(jié)構(gòu)經(jīng)過了廣泛的測試和驗證,其穩(wěn)定性和可靠性遠(yuǎn)高于大多數(shù)自定義數(shù)據(jù)結(jié)構(gòu)。使用它們可以減少程序中的錯誤和異常豐富的功能:Python為這些內(nèi)置數(shù)據(jù)結(jié)構(gòu)提供了豐富的內(nèi)置方法,支持各種操作,如數(shù)據(jù)的迭代、排序、切片等。這些功能的實(shí)現(xiàn)如果要從零開始,將會非常耗時并且容易出錯因此,選擇Python的內(nèi)置數(shù)據(jù)結(jié)構(gòu)而不是自定義實(shí)現(xiàn),可以利用Python語言的強(qiáng)大能力,提高開發(fā)效率,保證程序的性能和可靠性,同時也讓代碼更加簡潔、易于理解和維護(hù)95.3列表列表(List):是一種用于保存一系列有序元素的集合例如,一張購物清單可以保存在一個List中,其中的物品是List中的元素;某人一天中打開的網(wǎng)頁URL組成的序列形成一個List,其中的URL是List中的元素。同一個列表中可存放不同類型的元素,如整型、浮點(diǎn)型、字符串、列表等List中的所有元素放在一對方括號`[]’中,相鄰元素之間使用逗號隔開。語法結(jié)構(gòu)[item1,item2,...,itemi,...]其中item1,item2,...,itemi,...是列表的元素,元素可以是不同類型。10列表存儲于表示列表的存儲列表中的元素存儲在有序連續(xù)的內(nèi)存空間中建議在列表末尾添加或刪除元素,列表處理效率較高;否則,在列表頭部或中部添加或刪除元素,會導(dǎo)致大量元素在內(nèi)存空間的移動,大幅降低處理效率列表的表示同一個List中元素的類型可以相同,也可以不同[10,20,30,40,50]

['China','Russia','USA','France','UnitedKingdom']

['IntroductiontoPython',49.50,'20210901',['author1','author2','author3']]行1中的List中元素均為整型,行2中的List中元素均為字符串,行3中的List元素有字符型、整型、列表等不同類型。11列表操作列表的操作對一個包含有多個元素的序列,一般常規(guī)操作是增加、刪除、修改和查詢,簡稱“增刪改查”。List也不例外12類別方法說明增加append(x)將元素x增加至列表尾部增加insert(index,x)將元素x增加至位置index處,原index處之后的元素整體后移刪除remove(x)在列表中刪除首次出現(xiàn)的、其值等于x的元素刪除pop(index)刪除并返回列表指定位置的元素,空值時為最后一個元素查詢index(x)返回第一個值為x的元素位置(即下標(biāo)),若找不到,則拋出異常查詢count(x)返回值為x的元素在列表中出現(xiàn)的次數(shù)修改reverse()對列表中元素進(jìn)行原地翻轉(zhuǎn)修改sort(key=None,reverse=False)對列表中的元素進(jìn)行排序列表的創(chuàng)建與刪除列表創(chuàng)建:使用賦值運(yùn)算法=將一個列表賦值給變量,即可創(chuàng)建列表對象list1=['beijing','shanghai','guangzhou','shenzhen']list2=[]#創(chuàng)建一個空列表可以利用函數(shù)list()將可迭代對象類型的數(shù)據(jù)裝換為List,如元組、range對象、字符串等list3=list((1,3,5,7,9))#(1,3,5,7,9)為元組,#list3為[1,3,5,7,9]list4=list(range(1,10,2))#list4為[1,3,5,7,9]list5=list(‘hello’)#list5為['h','e','l','l','o']列表刪除利用命令del刪除整個列表dellist113增加列表元素增加列表元素:增加列表中的元素(1)函數(shù)append(x):將列表尾部添加元素x。該方法不改變列表的首地址,屬于原地操作,操作效率高list1=[1,2,3,4]list1.append(5)#結(jié)果:[1,2,3,4,5](2)函數(shù)extend(iterable):將另一個可迭代對象iterable的所有元素添加至該列表對象的末尾。該方法也是原地操作#接上例list1.extend([6,7,8])#結(jié)果:[1,2,3,4,5,6,7,8](3)函數(shù)insert(i,x):將一個元素x添加至列表的指定位置i,如果i大于列表的長度,則元素會被添加到列表的末尾,屬于原地操作#接上例list1.insert(3,10)#結(jié)果:[1,2,3,10,4,5,6,7,8]在原列表list1的元素[1,2,3,4,5,6,7,8]中的index=3的位置,即‘4’所處位置,增加10,元素4及其以后的元素整體后移,形成結(jié)果[1,2,3,10,4,5,6,7,8]。該方法引起大量其他元素的移動,效率較低,非必要,避免使用該方法14列表的乘法與加法(4)乘法*:列表乘以整數(shù)k,生成一個原列表元素重復(fù)k倍的新列表。該方法因創(chuàng)建新列表,非原地操作。list2=[1,2,3]list2=list2*3#結(jié)果[1,2,3,1,2,3,1,2,3]注意:使用*運(yùn)算符將列表元素復(fù)制時,并不真正創(chuàng)建元素值的副本,而是創(chuàng)建已有元素的引用。因此,修改其中一個元素的值,相應(yīng)的引用也被修改。list3=[[None]*2]*3#list3結(jié)果:[[None,None],[None,None],[None,None]]list3[0][0]=10#list3結(jié)果:[[10,None],[10,None],[10,None]](5)加法+:使用加法運(yùn)算符`+`可以將兩個列表合并成一個新列表。這個操作非常直接:它簡單地將第二個列表的元素追加到第一個列表的末尾,并返回這個組合后的新列表。值得注意的是,這個操作并不會改變原來的列表,而是創(chuàng)建一個全新的列表來存放結(jié)果。new_list=list1+list2這里,`list1`和`list2`是兩個已存在的列表,`new_list`將是一個包含了`list1`和`list2`所有元素的新列表。Python內(nèi)部實(shí)現(xiàn)過程是:已有一個原列表和一個元素,執(zhí)行+操作,創(chuàng)建一個新列表,將原列表中的元素和新元素依次復(fù)制至新列表。這種方式涉及大量元素的復(fù)制,效率低,不建議使用。list1=[1,2,3,4]list1=list1+[5]#結(jié)果:[1,2,3,4,5]15刪除列表元素刪除列表元素:刪除列表中的元素(1)del命令:刪除列表中指定位置上的元素list1=[1,3,5,7,9]dellist1[2]#結(jié)果:[1,3,7,9](2)函數(shù)pop():pop()函數(shù)是列表(list)的一個非常實(shí)用的方法。它用于移除列表中的一個元素(默認(rèn)是最后一個元素),并且返回該元素的值。這個方法既可以改變列表的長度,又能讓我們獲取被移除的元素的值,這使得`pop()`在處理棧(后進(jìn)先出LIFO)結(jié)構(gòu)時特別有用。element=list.pop(index=-1)list是要從中移除元素的目標(biāo)列表。index是可選參數(shù),指定要移除并返回的元素的索引位置。如果不提供`index`,`pop()`方法默認(rèn)移除并返回列表中的最后一個元素。element是被移除的元素的值。x=list1.pop(2)#結(jié)果:x為7,list1為[1,3,9](3)函數(shù)remove(x):刪除列表中首次出現(xiàn)的指定元素的值x,若列表中不存在要刪除的值,則拋出異ValueErrorlist2=[1,3,5,3,7]list2.remove(3)#結(jié)果:[1,5,3,7]16列表元素操作訪問和修改列表元素:使用下標(biāo)訪問列表中的元素,若下標(biāo)不存在,則拋出“下標(biāo)越界”異常;利用賦值操作=,將新值賦值給指定下標(biāo)的元素,實(shí)現(xiàn)列表元素的修改list1=[2,4,6,8]x=list1[0]#結(jié)果:x為2list[1]=10#修改位置為1的元素值,結(jié)果:[2,10,6,8]list[4]#結(jié)果:拋出下標(biāo)越界異常使用列表的函數(shù)index(value),獲取指定元素value首次出現(xiàn)的下標(biāo)(位置)list1=[2,4,6,8]pos=list1.index(6)#結(jié)果:pos為2判斷列表元素是否存在:使用關(guān)鍵詞in判讀列表中是否存在指定的值list1=[2,4,6,8]6inlist1#結(jié)果:True10inlist1#結(jié)果:False17列表切片切片(slice):是對序列型對象(如list、tuple、string等)的一種高級索引方法。普通索引只取出序列中的一個下標(biāo)對應(yīng)的元素,而切片則可以取出序列中一個范圍內(nèi)對應(yīng)的元素,且該范圍用戶可自定義,既可以是連續(xù)范圍,也可以是離散范圍語法結(jié)構(gòu)list_name[start:stop:step]其中l(wèi)ist_name為列表對象,start為切片的開始位置(默認(rèn)為0),stop為切片的終止位置(默認(rèn)為列表長度),step為切片的步長(默認(rèn)為1)。當(dāng)步長省略時,第二個冒號也一并省略切片區(qū)間由start和stop組成的區(qū)間是一個前閉后開區(qū)間,切片包括start位置的元素,但不包括stop位置的元素。a=list(range(10))#a為[0,1,2,3,4,5,6,7,8,9]a[:5]#結(jié)果:[0,1,2,3,4]a[1:6]#結(jié)果:[1,2,3,4,5]a[::2]#結(jié)果:[0,2,4,6,8]18負(fù)數(shù)下標(biāo)索引負(fù)數(shù)下標(biāo)索引:在切片中的start和stop索引,既可以取零和正數(shù),也可以取負(fù)數(shù)非負(fù)索引表示列表從前往后從0開始的索引而負(fù)數(shù)索引表示列表從后往前從-1開始的索引,依次為-1、-2、-3、....。非負(fù)小標(biāo)索引和負(fù)數(shù)下標(biāo)索引組成了有效索引范圍。索引范圍示意表a=list(range(11,21))#a為[11,12,13,14,15,16,17,18,19,20]

a[6:-1]#結(jié)果:[17,18,19]

a[-6:-1]#結(jié)果:[15,16,17,18,19]19列表元素11121314151617181920非負(fù)下標(biāo)0123456789負(fù)數(shù)下標(biāo)-10-9-8-7-6-5-4-3-2-1超出有效索引范圍超出有效索引范圍:對于使用下標(biāo)的基本索引,超出有效索引范圍,索引操作會拋出IndexError異常list1=[1,2,3]list1[3]運(yùn)行上述程序,拋出異常信息IndexError:listindexoutofrange。原因是list1只有3個元素,索引分別為0,1,2,讀取索引index=3位置上的元素,出現(xiàn)越界。對于切片索引,超出有效索引范圍,切片操作不會拋出異常,而是進(jìn)行截斷,即忽略超出有效索引的范圍。a=list(range(10))#a為[0,1,2,3,4,5,6,7,8,9]a[-100:6]#結(jié)果:[0,1,2,3,4,5]a[6:100]#結(jié)果:[6,7,8,9]a[5:3]#結(jié)果:[],因start>stop,無效,但無異常20基于切片的增刪改查基于切片的增刪改查:利用切片找到列表的一個索引范圍,然后對該范圍的元素進(jìn)行增刪改查。list1=[1,3,5,7,9]

list1[1:]#列表查詢,切片為[3,5,7,9]

list1[:3]=[10,20,30]#列表元素修改,list1為[10,20,30,7,9]

list1[:2]=[]#列表元素刪除,list1為[30,7,9]

dellist1[:2]#列表元素刪除,list1為[9]

list1[len(list1):]=11#列表尾部增加元素,list1為[9,11]21切片的副本數(shù)據(jù)結(jié)構(gòu)的復(fù)制:可分為淺復(fù)制和深復(fù)制淺復(fù)制:切片返回的是淺復(fù)制,即生成一個新列表,將原列表中所有元素的引用復(fù)制至新列表中若原列表中包含整數(shù)、實(shí)數(shù)、復(fù)數(shù)等基本類型,或者元組、字符串等不可變類型的數(shù)據(jù),一般沒問題。但列表中包含可變類型的數(shù)據(jù)時,原列表與新列表會共享可變類型的值list1=[1,3,5,7]

list2=list1[:]

#基本類型、不可變類型的淺復(fù)制

list1==list2#結(jié)果:True,兩個列表中的元素相同

list1islist2#結(jié)果:False,兩個列表不是同一個對象

list1[1]=4#list1為[1,4,5,7]

list1==list2#結(jié)果:False,兩個列表中的元素不相同了

#可變類型的淺復(fù)制

list3=[1,[3],5,7]

list4=list3[:]#結(jié)果:list4為[1,[3],5,7]

list3[1].append(4)#結(jié)果:[1,[3,4],5,7]

list4==list3#結(jié)果:True,list4中的index=1位置的隊列也自動變?yōu)閇3,4],即list4為[1,[3,4],5,7]22切片的副本深復(fù)制:當(dāng)從一個列表復(fù)制得到第二個列表,并希望兩個列表之后的各自修改不會相互影響,不管其中是基本類型、不可變類型和可變類型。這需要采用深復(fù)制,即將一個列表中的所有元素(無論是不可變還是可變類型的對象)復(fù)制到第二個列表中。為此,需要使用模塊copy的深度復(fù)制函數(shù)deepcopy()。importcopylist5=[1,[3],5,7]list6=copy.deepcopy(list5)#深度復(fù)制,list6為[1,[3],5,7]list5[1].append(4)#list5為[1,[3,4],5,7]list5==list6#結(jié)果:False,因list6依然為[1,[3],5,7]23列表排序?qū)⒘斜碇械脑剡M(jìn)行排序,有sort()和sorted()兩種方法sort()方法利用sort()進(jìn)行列表的原地排序,沒有返回值list1=[10,25,5,36,80,68]list1.sort()#結(jié)果:list1為[5,10,25,36,68,80]list1.sort(reverse=True)#結(jié)果:list1為[80,68,36,25,10,5]在Python的list類型中,sort()方法可以接受一個key參數(shù),這個參數(shù)可指定一個函數(shù),該函數(shù)將在每個元素上調(diào)用并返回一個用于排序的值。這可實(shí)現(xiàn)復(fù)雜的排序邏輯,而不僅僅是基于元素的原始值進(jìn)行簡單排序。24列表排序按字符串長度排序假設(shè)有一個字符串列表,按照字符串的長度進(jìn)行排序。words=['banana','apple','cherry','date']words.sort(key=len)print(words)按字典中的值排序假設(shè)有一個字典列表,根據(jù)每個字典中特定鍵的值進(jìn)行排序data=[{'name':'Alice','age':30},{'name':'Bob','age':25},{'name':'Charlie','age':35}]data.sort(key=lambdax:x['age'])print(data)25列表排序多條件排序:假設(shè)根據(jù)多個維度(或?qū)傩裕α斜磉M(jìn)行排序,比如先按年齡排序,年齡相同則按名字排序。data.sort(key=lambdax:(x['age'],x['name']))print(data)這將先按age排序,如果age相同,則按name排序sort()方法會就地修改列表,如果想保留原始列表不變,可以使用sorted()函數(shù)key函數(shù)應(yīng)當(dāng)對每個元素返回一個值,該值將用于比較元素的順序使用lambda函數(shù)可以方便地定義簡單的key函數(shù),但對于更復(fù)雜的邏輯,需要自定義一個函數(shù)來實(shí)現(xiàn)通過使用key參數(shù),sort()方法提供了一種強(qiáng)大且靈活的方式來定義自定義排序邏輯,從而使得Python的列表排序功能更加強(qiáng)大26列表排序sorted()函數(shù)利用函數(shù)sorted()創(chuàng)建一個新列表,對原列表進(jìn)行排序后,其結(jié)果存放于新列表中,并返回新列表該函數(shù)對原列表不做任何修改list1=[10,25,5,36,80,68]

list2=sorted(list1)結(jié)果:list1為[10,25,5,36,80,68],list2為[5,10,25,36,68,80]27列表逆序reverse()函數(shù)利用方法reverse()將列表中的所有元素原地逆序,即首尾對調(diào)注意逆序并非降序list1=[10,25,5,36,80,68]list1.reverse()#結(jié)果:list1為[68,80,36,5,25,10]reversed()函數(shù)利用函數(shù)reversed()創(chuàng)建一個新列表,對原列表逆序操作后,其結(jié)果存放于新列表中,并返回新列表。該函數(shù)對原列表不做任何修改list1=[10,25,5,36,80,68]list2=list(reversed(list1))

#結(jié)果:list1為[10,25,5,36,80,68],list2為[68,80,36,5,25,10]28列表推導(dǎo)式在Python中,一般從一個數(shù)據(jù)序列構(gòu)建另一個新的數(shù)據(jù)序列,可以采用一種特殊的數(shù)據(jù)處理方式——Python推導(dǎo)式Python支持各種數(shù)據(jù)結(jié)構(gòu)的推導(dǎo)式:列表(list)推導(dǎo)式、字典(dict)推導(dǎo)式、集合(set)推導(dǎo)式、元組(tuple)推導(dǎo)式語法結(jié)構(gòu)[expressionforvariableiniterableifcondition]其中expression為表達(dá)式,variable為變量,iterable為可迭代對象,condition為條件。舉例:list1=[x*xforxinrange(5)]#結(jié)果:list1為[0,1,4,9,16]29列表推導(dǎo)式的一些應(yīng)用:嵌套列表的平鋪:利用多個循環(huán)嵌套讀取。list2=[[1,2,3],[4,5,6],[7,8,9]][numforelementinlist2fornuminelement]#結(jié)果:[1,2,3,4,5,6,7,8,9]過濾不符合條件的元素:利用條件語句實(shí)現(xiàn)元素過濾。list3=[2,-10,9,4.6,-2,0][iforiinlist3ifi>0]#結(jié)果:[2,9,4.6],找出正數(shù)海象操作符(:=)可以用于列表推導(dǎo)式中,為元素賦值并進(jìn)行條件判斷。#使用海象操作符values=[yforxinrange(10)if(y:=x*2)>5]#結(jié)果:[6,8,10,12,14,16,18]理論上,列表推導(dǎo)式可以包含多個for循環(huán)和if條件語句,這使得它們非常強(qiáng)大且靈活。然而,在實(shí)際編程實(shí)踐中,推薦列表推導(dǎo)式最多包含兩個子表達(dá)式(例如,兩個if條件、兩個for循環(huán),或者一個if條件與一個for循環(huán))。這是為了確保代碼的可讀性和易于維護(hù),復(fù)雜的列表推導(dǎo)式往往難以理解和修改,而使用簡單的結(jié)構(gòu)可以使代碼更加清晰和高效30Python內(nèi)置函數(shù)計算分?jǐn)?shù)列表中的最高分、最低分和平均分。scores=[80,76,92,85,62,56,98,78]highest=max(scores)lowest=min(scores)average=sum(scores)/len(scores)print("Highestscore:",highest,";Lowestscore:",lowest,";Averagescore",average)其中函數(shù)max(list),min(list),sum(list)和len(list)為Python的內(nèi)置函數(shù),分別計算函數(shù)參數(shù)列表中的最大值、最小值、求和以及列表長度(即列表中元素數(shù)量)根據(jù)PEP8規(guī)范,當(dāng)需要判斷一個列表或集合是否為空時,由于性能的原因不推薦使用長度來判斷(例如iflen(list1)==0)。而是應(yīng)該直接使用not語句(例如ifnotlist1),這是由于在Python中空的列表或集合被自動視為False。同理,當(dāng)需要判斷一個列表或集合是否有內(nèi)容時,應(yīng)該采用iflist1,非空的列表或集合自動視為True31enumerate假設(shè)有一個列表,需要遍歷它并同時跟蹤每個元素的索引。常規(guī)做法是使用一個計數(shù)器變量:fruits=['apple','banana','cherry']index=0forfruitinfruits:print(index,fruit)index+=1這種方法雖然可行,但不夠優(yōu)雅。enumerate是一個內(nèi)置函數(shù),它允許在遍歷一個序列的同時跟蹤元素的索引。它將一個可迭代對象(如列表、元組或字符串)轉(zhuǎn)換為一個枚舉對象。這個枚舉對象生成包含每個元素索引及其值的元組基本迭代場景:fruits=['apple','banana','cherry']forindex,fruitinenumerate(fruits):print(index,fruit)32enumerate指定起始索引的迭代場景:可以指定一個起始索引值,這在不同的上下文中非常有用。forindex,fruitinenumerate(fruits,start=1):

print(index,fruit)在列表推導(dǎo)式中使用:indexed_fruits=[(index,fruit)forindex,fruitinenumerate(fruits)]

print(indexed_fruits)通過使用enumerate,可以優(yōu)雅地解決需要索引的迭代問題,使得代碼更加Pythonic,而且內(nèi)存的使用效率更高33內(nèi)存中的列表List是一個動態(tài)數(shù)組,其中存儲的元素是指向內(nèi)容的指針,list的大小可變化。List在分配內(nèi)存時,采用過度分配機(jī)制:當(dāng)給列表中插入(append或insert)一項元素時,但原來分配給列表的空間已滿,這時創(chuàng)建一個新列表,設(shè)置其大小較原列表大小大若干個元素,以備以后再插入元素的需要。list的append操作list初始化后,在list中追加第一個元素data_1=5,這時list會開辟4個元素空間,在第一個元素里存放data_1的地址,其余元素申請了內(nèi)存,當(dāng)并未使用,如圖(a)所示。隨后依次調(diào)用append(9)、append(3)和append(16),其list中存儲的分別是9、3和16三個元素的首地址。34(a)list.append(5)(b)list.append(9)(c)list.append(3)(d)list.append(16)list1=[]print('Initialsize:',list1.__sizeof__())foriinrange(1,6):list1.append(i)print(list1,'\'ssize:',list1.__sizeof__())輸出結(jié)果Initialsize:40[1]'ssize:72[1,2]'ssize:72[1,2,3]'ssize:72[1,2,3,4]'ssize:72[1,2,3,4,5]'ssize:104由輸出結(jié)果可知,期初一個空的列表占40個字節(jié),添加第一個元素,列表占72個字符,之后依次增加第2、3、4元素,列表占用空間大小不變,直到增加第5個元素時,列表有出現(xiàn)了超額分配空間,占用104個字符35list的insert操作在上例中的列表list中,在index為1的位置上插入一個元素25,此時產(chǎn)生如下操作創(chuàng)建一個新列表list_2,元素空間大小增加到8。這種一次性分配若干個元素空間,以后再append或insert若干個元素時,不用再創(chuàng)建新的list,減少了創(chuàng)建新列表并拷貝元素操作將原有列表list_1中的index之前的元素拷貝到相同index的新列表list_2中,index之后的所有元素,在新列表中位置均后移一位產(chǎn)生一個新元素25,將這個新元素的首地址存儲在index為1的list_2中36list的pop操作list的pop操作是彈出list最末位置的一個元素。當(dāng)該操作執(zhí)行結(jié)束后,元素占用的空間數(shù)小于分配空間數(shù)的一半時,申請的內(nèi)存空間將會縮小。375.4元組元組(Tuple)是不可變的序列,用一對小括號"()"囊括一系列元素,元素之間用逗號隔開。它可以看做為輕量級列表。列表是可變序列,可增加、刪除和修改列表的元素;元組為不可變序列,一旦定義不允許任何修改。因此,對元組的增刪改操作均無法使用元組的用途和優(yōu)勢體現(xiàn)在:由于不可變性,元組可以用作字典的鍵(而列表不可以)。元組在創(chuàng)建時間和內(nèi)存使用上通常比列表更高效可以用作函數(shù)間傳遞的結(jié)構(gòu)化數(shù)據(jù),提供一種保證數(shù)據(jù)不會被修改的安全性。38創(chuàng)建元組創(chuàng)建元組:使用賦值操作=將一個元組賦值給元組變量tuple1=(1,2,3,4,5)

tuple2=()#空元組當(dāng)元組中只包含一個元素時,需要在元素后面添加一個逗號tuple3=(10,)沒有逗號的話,Python會將其視為普通的括號運(yùn)算,而不是一個元組。例如,如果寫下my_tuple=(5),Python會認(rèn)為這是一個數(shù)值5,而不是包含5的元組。為了明確地告訴Python你想創(chuàng)建的是一個元組,你需要寫成my_tuple=(5,)。39元組的訪問、修改和刪除訪問元組:可以采用下標(biāo)索引訪問元組中的元素。tuple4=('math',90,'physics',95)tuple4[0]#結(jié)果:'math'tuple4[2:4]#結(jié)果:('physics',95)修改元組:元組中的元素不允許修改,但可以將多個元組進(jìn)行合并tuple5=('math','physics')tuple6=(90,95)tuple7=tuple5+tuple6#結(jié)果:('math','physics',90,95)刪除元組:元組中的元素不允許刪除,但可使用del語句刪除整個元組tuple4=('math',90,'physics',95)deltuple4#刪除整個元組tuple440序列解包序列解包(unpacking):是一種允許將一個可迭代對象(如列表、元組、字典、字符串等)解開,并將其內(nèi)部的值分別賦給一系列變量的語法。這種機(jī)制在Python中廣泛使用,使得從可迭代對象中提取元素變得簡潔高效。其核心應(yīng)用場景包括:變量賦值:在變量初始化時,可直接從列表或元組等數(shù)據(jù)結(jié)構(gòu)中提取元素值函數(shù)返回值處理:函數(shù)可以返回多個值(實(shí)際上以元組形式),通過序列解包,可以將這些值分別賦給不同的變量x,y,z=1,2,3tuple1=('shanghai',2024,6341)city,year,area=tuple1#結(jié)果:city為‘上?!?,year為2024,area為6341平方公里(city,year,area)=tuple1#等價上句41交換變量值:在Python中,可以利用序列解包來方便地交換兩個變量的值,無需額外使用臨時變量。a=5b=10a,b=b,a#結(jié)果:a的值變?yōu)?0,b的值變?yōu)?忽略不需要的變量:當(dāng)解包序列時,如果不需要序列中的某些值,可以使用下劃線(_)作為占位符來忽略這些值。data=(1,2,3,4,5)first,_,third,_,fifth=data#結(jié)果:first=1,third=3,fifth=542解包嵌套的序列:序列解包也可以應(yīng)用于嵌套的序列(例如列表中的列表或元組)nested_list=[(1,'apple'),(2,'orange')]fornumber,fruitinnested_list:print(f"Number{number}isfor{fruit}")在函數(shù)調(diào)用中使用拆包:序列解包不僅可以在變量賦值中使用,還可以在函數(shù)調(diào)用中使用。這種方法特別有用,因為它允許動態(tài)地從序列或字典結(jié)構(gòu)中傳遞參數(shù)到函數(shù),無需在函數(shù)調(diào)用時顯式地列出每個參數(shù)使用*可以將列表或元組拆包作為位置參數(shù)使用**可以將字典拆包作為關(guān)鍵字參數(shù)deffunc(x,y,z):

print(x,y,z)

tuple_args=(1,2,3)

func(*tuple_args)

dict_args={'x':1,'y':2,'z':3}

func(**dict_args)43zip()函數(shù)zip()函數(shù)是Python中的一個內(nèi)置函數(shù),它的作用是將多個可迭代對象(如列表、元組或字符串)中對應(yīng)的元素打包成一個個元組,然后返回這些元組組成的對象,通常用于并行迭代多個可迭代對象。zip()函數(shù)一般有兩個典型用途:并行迭代:zip()允許同時遍歷多個序列,這在處理具有相關(guān)聯(lián)的數(shù)據(jù)時非常有用數(shù)據(jù)重組合:它經(jīng)常被用來將數(shù)據(jù)重新組合為鍵值對,使得數(shù)據(jù)處理更加靈活和方便keys=['廣東','山東','河南']#省份列表values=[126012510,101527453,99365519]#2020年人口數(shù)fork,vinzip(keys,values):print(k,v)zip()函數(shù)返回的是一個zip對象,它是一個迭代器。要查看它包含的元素,需要將其轉(zhuǎn)換為列表或其他數(shù)據(jù)結(jié)構(gòu)如果提供給zip()的序列長度不一致,zip()會停止在最短的序列用盡的位置。如果需要處理不同長度的序列,可以考慮使用itertools.zip_longest()44帶*的拆包帶有星號的表達(dá)式(starredexpression):也可用于拆包操作,它可將無法由普通變量接收的剩余元素全部囊括進(jìn)去。car_prices=[50,26,14,80,150,10,5,30]car_prices_descending=sorted(car_prices,reverse=True)highest,*others,lowest=car_prices_descendingprint(highest,lowest,others)highest被賦值為列表的第一個元素,代表最高的價格值;lowest被賦值為列表的最后一個元素,代表最低的價格值;而*others收集了列表中間的所有其余元素,即除了最高和最低價格之外的所有價格。這一處理方式可視為拆包的一種特殊應(yīng)用,其中帶星號的變量(*others)執(zhí)行了類似于列表切片的角色,但以更直觀和靈活的方式,直接在變量賦值過程中實(shí)現(xiàn)了這一操作45生成器表達(dá)式列表推導(dǎo)式可方便的從現(xiàn)有數(shù)據(jù)集合生成新列表,盡管在多數(shù)情況下效率高且易于編寫,但在在處理大規(guī)模數(shù)據(jù)時存在一定局限性。其問題在于:列表推導(dǎo)式采用的是一次性生成整個結(jié)果集的策略,導(dǎo)致處理龐大數(shù)據(jù)集時內(nèi)存消耗顯著增加。隨著待處理數(shù)據(jù)的體量增長,這種策略可能造成程序運(yùn)行時可用內(nèi)存的迅速耗盡,進(jìn)而影響到程序的執(zhí)行性能及其可操作性為了解決這一問題,Python引入了生成器表達(dá)式(GeneratorExpressions)生成器表達(dá)式采用與列表推導(dǎo)式相似的語法結(jié)構(gòu),但它不會一次性生成一個完整的數(shù)據(jù)集合就,而是返回一個迭代器,該迭代器按需逐個生成元素,實(shí)現(xiàn)了所謂的惰性求值(lazyevaluation)這種按需生成元素的特性顯著減少了內(nèi)存的使用,因為在任意時刻,只有迭代到的當(dāng)前元素被處理和存儲在內(nèi)存中46生成器表達(dá)式生成器表達(dá)式語法結(jié)構(gòu)(<expression>for<var>in<iterable>if<condition>)相當(dāng)于以下代碼for<var>in<iterable>:ifbool(<condition>):yield<expression>與列表推導(dǎo)式不同之處在于:形式上,列表推導(dǎo)式為方括號,生成器表達(dá)式為圓括號訪問上,列表推導(dǎo)式的迭代對象可以反復(fù)訪問,而生成器表達(dá)式的迭代對象只能訪問一次,再次訪問將不復(fù)存在。若再次使用,需要再次創(chuàng)建返回結(jié)果上,列表推導(dǎo)式返回一個列表,而生成器表達(dá)式返回一個生成序列的方法,即一個迭代器generator=print(genera(i*iforiinrange(5))tor)#輸出:<generatorobject<genexpr>at...>print(tuple(generator))#輸出:(0,1,4,9,16)print(tuple(generator))#輸出:()47迭代器迭代器(Iterator):是Python中一個核心的抽象概念,它允許以一種統(tǒng)一的方式遍歷各種數(shù)據(jù)結(jié)構(gòu)——無論是列表、字典、文件,還是那些更加復(fù)雜的數(shù)據(jù)結(jié)構(gòu)迭代器背后的主要思想是“惰性求值”,這意味著數(shù)據(jù)項是在需要的時刻才被計算和返回。這種機(jī)制不僅節(jié)約內(nèi)存資源,還能夠表示和操作潛在地?zé)o限大的數(shù)據(jù)流。實(shí)際上,生成器表達(dá)式就是建立在迭代器接口之上的,提供了一種靈活構(gòu)造迭代器的方法。迭代器的引入為Python的數(shù)據(jù)處理與遍歷提供了極大的靈活性和強(qiáng)大的抽象能力。通過實(shí)現(xiàn)迭代器協(xié)議,即__iter__()和__next__()方法,任何對象都可以成為可迭代的,開放了一個廣泛的,能夠通過統(tǒng)一方式處理的數(shù)據(jù)世界__iter__()方法:返回迭代器對象本身__next__()方法:返回迭代器的下一個元素,并在沒有更多元素時拋出StopIteration異常這不僅簡化了數(shù)據(jù)訪問,還鼓勵了更加模塊化和高效的代碼設(shè)計48生成器生成器是Python中一種特殊類型的迭代器,其核心在于使用yield關(guān)鍵字而不是return返回值。當(dāng)生成器函數(shù)被調(diào)用時,它不會立即執(zhí)行函數(shù)體內(nèi)的代碼,而是返回一個生成器對象。這個對象支持迭代協(xié)議,能夠逐個產(chǎn)生(而非一次性生成)函數(shù)中通過yield表達(dá)式指定的序列值與普通迭代器相比,生成器提供了一種更為簡潔的創(chuàng)建方式。僅通過定義帶有yield的函數(shù)來構(gòu)建復(fù)雜的迭代邏輯,而無需手動實(shí)現(xiàn)__iter__()和__next__()方法簡而言之,生成器彌補(bǔ)了傳統(tǒng)迭代器實(shí)現(xiàn)上的復(fù)雜性,提供了一種資源高效且編寫簡潔的數(shù)據(jù)迭代方案。通過使用生成器,開發(fā)者能夠在保證性能的同時,實(shí)現(xiàn)清晰和易于維護(hù)的數(shù)據(jù)處理邏輯49內(nèi)存中的元組元組:使用一個固定大小的數(shù)組來實(shí)現(xiàn)的,為不可變的容器,一旦創(chuàng)建,其內(nèi)部包含的元素引用不允許更改列表:設(shè)計為可變?nèi)萜?,允許修改、添加和刪除其內(nèi)部元素引用。列表為了支持動態(tài)變化的性質(zhì),通常會使用更多的內(nèi)存空間來預(yù)留額外的容量,以優(yōu)化性能因此,在需要存儲不變集合的場景下,使用元組而不是列表,可以更有效地利用內(nèi)存list1=[1,2,3]tuple1=(1,2,3)print('Sizeoflist[1,2,3]:',list1.__sizeof__())print('Sizeoftuple(1,2,3):',tuple1.__sizeof__())輸出結(jié)果Sizeoflist[1,2,3]:64Sizeoftuple(1,2,3):48505.5字典字典(Dictionary):是一個包含若干“key:value”對的無序可變序列。字典的每一個元素包含兩部分:key(鍵)和value(值),類似于漢語字典,key是某一個漢字,value是對該漢字的解釋。字典語法結(jié)構(gòu){key1:value1,key2:value2,...}字典中的key可以為任何不可變數(shù)據(jù)類型,如整數(shù)、浮點(diǎn)數(shù)、復(fù)數(shù)、字符串、元素有不可變數(shù)據(jù)類型的元組等,但不可以為可變數(shù)據(jù)類型,如列表、字典、集合、以及元素有可變數(shù)據(jù)類型的元組。字典的key不允許重復(fù)。51創(chuàng)建字典方法一:使用=將一個字典賦值給一個字典變量dict1={'AI':'artificialintelligence','DL':'deeplearning','ML':'machinelearning'}dict2={}#空字典按照PEP8的規(guī)范,字典中的鍵與冒號之間不加空格,而冒號與值之間應(yīng)該加一個空格方法二:使用函數(shù)dict(),根據(jù)已有數(shù)據(jù)創(chuàng)建字典keys=['name','gender','age']values=['LiMing','male',16]dict3=dict(zip(keys,values))#結(jié)果:dict3是{'name':'LiMing','gender':'male','age':16}dict4=dict()#空字典dict5=dict(name='LiMing',age=16)#結(jié)果:dict5為{'name':'LiMing','age':16}52刪除字典使用del命令刪除整個字典,或刪除字典中指定的元素dict6={'id':'001','name'='Tom','age'=20}deldict6['age']#刪除了'age'=20條目deldict6#刪除整個字典字典對象的clear():刪除字典中所有元素字典對象的pop(key):刪除并返回指定“鍵”的元素prices={'apple':5,'grape':10,'strawberry':20}element=prices.pop('strawberry')print('Thepoppedelmentis:',element)print('Thedictionaryis:',prices)字典對象的popitem():刪除并返回字典中最后一對鍵值對(key,value)person={'name':'Adam','age':25,'salary':5000}item=person.popitem()print('Returnitemis:',item)print('Thetypeofreturnitemis:',type(item))print('Personis:',person)53添加和修改字典元素當(dāng)以指定key對字典元素賦值時,若該key存在,則修改該key的value;若該key不存在,則添加一個新的“key:value”對dict7={'name’:’LiMing','age':16}dict7['age']=17#將原來的age為16修改為17dict['phone']=#添加新元素還可通過字典對象的update()函數(shù)將另一個字典的所有“key:value”添加到當(dāng)前字典對象中。如果兩個字典存在相同key,則以另一個字典中的value為準(zhǔn)dict1={'a':1,'b':2}dict2={'a':5,'d':6}dict1.update(dict2)print(dict1)#{'a':5,'b':2,'d':6}54鍵不存在時的處理方法處理字典時常遇到的一個問題是如何處理在字典中不存在的鍵,常見方法有:(1)使用get()方法:get()方法是訪問字典鍵的一種安全方式。如果鍵存在于字典中,它將返回相應(yīng)的值;如果不存在,它將返回一個默認(rèn)值。my_dict={'a':1,'b':2}value=my_dict.get('c','default_value')print(value)#輸出:default_value(2)使用in關(guān)鍵字進(jìn)行檢查:在嘗試訪問鍵值之前,可以使用in關(guān)鍵字來檢查鍵是否存在于字典中if'c'inmy_dict:value=my_dict['c']else:value='default_value'print(value)#輸出:default_value(3)使用setdefault()方法:setdefault()方法在鍵不存在時,會在字典中添加該鍵并設(shè)置默認(rèn)值value=my_dict.setdefault('c','default_value')print(value)#輸出:default_value55字典推導(dǎo)式字典推導(dǎo)式(dictionarycomprehension):提供了一種從可迭代對象生成字典的簡潔方法,是一種在Python中創(chuàng)建字典的高效且易讀的方式基本語法{key:valueforkey,valueiniterableifcondition}其中,key和value分別代表字典中的鍵和值,iterable是一個可迭代對象,而condition是一個可選的條件表達(dá)式,用于決定哪些元素應(yīng)該被包含在新字典中字典推導(dǎo)式常用于數(shù)據(jù)過濾、快速生成字典、數(shù)據(jù)轉(zhuǎn)換等場景。它們尤其在需要將一個字典或其他數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)換為字典時非常有用注意:在使用字典推導(dǎo)式時,需要注意鍵的唯一性。如果字典推導(dǎo)式中存在重復(fù)的鍵,那么最終字典中將只包含這些鍵的最后一個值56舉例:字典推導(dǎo)式基本用法{k:vfork,vin[(1,2),(3,4)]}#輸出:{1:2,3:4}使用range生成鍵值對{n:n*2forninrange(3)}#輸出:{0:0,1:2,2:4}從元組序列創(chuàng)建字典{k:vfork,vin(('I',1),('II',2))}#輸出:{'I':1,'II':2}加入條件表達(dá)式{k:vfork,vin(('a',0),('b',1),('c',2))ifv>0}#輸出:{'b':1,'c':2}57內(nèi)存中的字典list和tuple是通過位置(即索引)可快速獲得集合的元素dict是通過將關(guān)鍵詞轉(zhuǎn)化為集合中的位置,從而再通過位置獲得該元素,即采用哈希表(hashtable)的概念來解決這類問題,查找速度很快,時間復(fù)雜度為O(1)。哈希表的基本原理是:利用哈希函數(shù)(hashfunction),將一個key值映射成一個數(shù)組的索引,將key值對應(yīng)的value存儲在該索引對應(yīng)的數(shù)組元素中。習(xí)慣上,這種存放value的數(shù)組稱為桶(buckets)585.6集合集合(set):是一個可變的無序序列,且集合中的元素不允許重復(fù)。集合元素可以是不同類型,如整型、浮點(diǎn)型、元組和字典等,但是,不能為可變的元素,如列表、集合或字典它通常用來從列表中刪除重復(fù)項,或者計算數(shù)學(xué)中的集合運(yùn)算,如交集、并集、差分和對稱差分等語法結(jié)構(gòu){itme1,item2,...}59創(chuàng)建集合賦值操作符=:將一個集合直接賦值給一個集合對象letters={'a','b','c','d'}my_set={1.0,'hello',(1,2,3)}函數(shù)set():使用set()函數(shù)將可迭代對象轉(zhuǎn)化為集合,若原來數(shù)據(jù)中存在重復(fù)元素,轉(zhuǎn)化后的集合中只保留一個重復(fù)元素set0=set()set1=set(range(1,6))#結(jié)果:{1,2,3,4,5}set2=set([1,3,4,8,4,3,5])#結(jié)果:set2為{1,3,4,8,5}60增加集合元素添加集合的元素:利用set.add(elem),將元素elem添加至當(dāng)前集合。如果原集合中存在該元素elem,則原集合保持不變set1=set('hello’)#輸出:{'l','h','e','o'}set1.add('q’)#輸出:{'l','e','o','h','q’}添加iterable中的元素:利用set.update(iter1,iter2,...,itern),給一個set增加一個或多個iterable對象中的所有元素,如list、set、dictionary和string等,函數(shù)返回值為nullset1={'a','b','c'}set2={1,2,3}set3={9.8,3.14}set1.update(set2,set3)print('set1=',set1)#set1={1,'a',2,3,3.14,9.8,'c','b'}61刪除集合元素刪除集合的元素:利用set.pop()隨機(jī)刪除集合中的一個元素,并把該元素值返回set1=set('hello')elem=set1.pop()print(elem)#輸出‘l’print(set1)#輸出{'h','e','o’}清空集合所有元素:利用clear()刪除集合中的所有元素set1=set('hello')set1.clear()print(set1)#輸出空集合刪除指定的值:使用set.discard(x),刪除集合中的元素x,如果set中無x元素,不做操作。也可以使用set.remove(x),刪除集合中的元素x,如果set中無該元素,將會拋出異常。numbers={1,2,3,4,5}numbers.discard(3)numbers.remove(4)numbers.remove(6)62集合推導(dǎo)式集合推導(dǎo)式(setcomprehension)是根據(jù)可迭代對象生成集合語法結(jié)構(gòu):{variableforvariable,variableininput_setifcondition}{sforsin[1,2,1,0,3]}{s**2forsin[1,2,1,0,3]}{sforsinrange(10)ifs%3==0}集合運(yùn)算:集合支持交集、并集、差集等運(yùn)算。有兩種方法:63方法一:利用并集、交集和差集的運(yùn)算符,分別為"|"、"&"和"-"。set3=set([1,3,5,7])set4=set([3,6,12,24])set3|set4#并集,結(jié)果:{1,3,5,7,6,12,24}set3&set4#交集,結(jié)果:{3}set3-set4#差集,結(jié)果:{1,5,7}方法二:利用set的函數(shù)A.union(*other_set)、A.intersection(*other_set)和A.difference(B),實(shí)現(xiàn)兩個集合的并集、交集和差集。A={'a','b','c','d'}B={'c','e','f'}print("A|B:",A.union(B))print("A&B:",A.intersection(B))print("A-B:",A.difference(B))舉例:集合從列表中刪除重復(fù)項list1=[1,2,3,2,3,'Finance','computer','Finance']list2=list(set(list1))print(list2)#[1,2,3,'Finance','computer']64Set的內(nèi)存管理Set是一種存儲元素?zé)o序且不重復(fù)的集合。元素?zé)o序使得增刪改查某一元素時,均需要查詢到集合中的該元素。為了提高查詢速度,Set也是通過哈希表實(shí)現(xiàn)65例1:等額本金還款除了等額本息還款方式外,等額本金還款也是一種常見的貸款還款方式。等額本金:貸款人每月歸還同等數(shù)額的貸款本金,貸款利息隨著本金逐月遞減。這樣的好處是,總的還款額相比等額本息還款會少,但是前期的還款壓力較大。等額本金的還款方式的核心在于每月歸還同等數(shù)額的本金,而利息則是根據(jù)剩余本金來計算。其計算公式如下:每月應(yīng)還本金=貸款本金/還款月數(shù)每月應(yīng)還利息=剩余貸款本金×月利率每月還款總額=每月應(yīng)還本金+每月應(yīng)還利息66defcalculate_monthly_payments_equal_principal(principal,annual_interest_rate,loan_years):“”“計算等額本金的每月還款金額。參數(shù):principal(float):貸款本金、annual_interest_rate(float):年利率、loan_years(int):貸款年數(shù)返回:list:每月還款金額的列表"""#計算還款月數(shù)

number_of_payments=loan_years*12#計算月利率

monthly_interest_rate=annual_interest_rate/12#計算每月應(yīng)還本金

monthly_principal=principal/number_of_payments#計算每月還款總額

monthly_payments=[]remaining_principal=principalforiinrange(number_of_payments):monthly_interest=remaining_principal*monthly_interest_ratemonthly_payments.append(monthly_principal+monthly_interest)remaining_principal-=monthly_principalreturnmonthly_payments#示例:如果你貸款100000元,年利率是5%,貸款期限是10年principal=100000annual_interest_rate=0.05loan_years=10monthly_payments=calculate_monthly_payments_equal_principal(principal,annual_interest_rate,loan_years)print(f"如果你貸款{principal}元,年利率{annual_interest_rate*100}%,貸款期限{loan_years}年,每月需要還款的金額如下:")fori,paymentinenumerate(monthly_payments,start=1):print(f"第{i}個月需還款:{payment:.2f}元。")67如果你貸款100000.00元,年利率5.0%,貸款期限10年,每月需要還款的金額如下:第1個月需還款:879.17元。第2個月需還款:875.00元。第3個月需還款:870.83元。第4個月需還款:866.67元。...第119個月需還款:462.50元。第120個月需還款:458.33元。68例2投資組合優(yōu)化模型需求:為投資組合分配不同的資產(chǎn)權(quán)重以最大化預(yù)期回報,同時考慮風(fēng)險。使用蒙特卡洛模擬生成大量隨機(jī)的資產(chǎn)權(quán)重,并選擇那些具有最佳風(fēng)險-回報權(quán)衡的投資組合。69importrandomdefportfolio_optimization(returns,risks,num_portfolios=10000):"""

使用蒙特卡洛模擬為投資組合選擇最佳權(quán)重。參數(shù):returns(list):各資產(chǎn)的預(yù)期回報率

risks(list):各資產(chǎn)的風(fēng)險

num_portfolios(int):模擬的投資組合數(shù)量返回:list:最佳投資組合的資產(chǎn)權(quán)重

"""num_assets=len(returns)best_return=0best_risk=float('inf')best_weights=[]for_inrange(num_portfolios):#隨機(jī)生成權(quán)重并歸一化

weights=[random.random()for_inrange(num_assets)]total_weight=sum(weights)weights=[w/total_weightforwinweights]

溫馨提示

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

評論

0/150

提交評論