信息安全案例教程:技術與應用 第2版 課件 第4章 非序列組合_第1頁
信息安全案例教程:技術與應用 第2版 課件 第4章 非序列組合_第2頁
信息安全案例教程:技術與應用 第2版 課件 第4章 非序列組合_第3頁
信息安全案例教程:技術與應用 第2版 課件 第4章 非序列組合_第4頁
信息安全案例教程:技術與應用 第2版 課件 第4章 非序列組合_第5頁
已閱讀5頁,還剩50頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第4章非序列組合信息學院2024引言4.1案例:四國宏觀經濟數據對比4.2字典4.3集合4.4JSON文件4.5編程實踐:Pygal4.6本章小結4.7習題本章將學習最后兩種數據類型:字典和集合。在此基礎上,還將學習常用的數據文件之一:JSON文件。在章首案例的指引下,本章還將學習使用一些標準庫和第三方庫。在編寫完成案例程序之后,就學會了讀取數據文件初步做一些數據分析和處理工作。4.1案例:四國宏觀經濟數據對比DataHub(https://datahub.io)是一個免費的公共數據平臺,提供了國際組織、不同國家、地方政府、研究機構發布的高質量數據集,涉及金融、醫療、社科、教育等眾多領域。本章案例搜集并下載的是世界各國1960年以來的人口、GDP和人均GDP的數據集,都是JSON(JavaScriptObjectNotation)文件,JSON是一種通用的輕量級的數據交換格式。編寫程序對中國、美國、英國和印度這四國60年來的宏觀經濟數據進行對比和展示,需要說明的是,該數據集中包含了世界所有國家的數據,我們選擇了這四國進行對比。首先讓用戶選擇要對比的數據文件,注意這里的文件類型限定為JSON文件(*.json)。本章案例可以選擇三個:“gdp_pcap.json”是世界各國的人均GDP數據,“gdp.json”是世界各國的GDP數據,“population.json”是世界各國的人口數據。4.1案例:四國宏觀經濟數據對比首先選擇“gdp_pcap.json”,程序運行后出現如下提示:Pleasecheckfile:gdp_pcap_compared.svg在和程序相同的文件夾下找到該圖形文件,雙擊用瀏覽器打開,可以看到對于中國、美國、英國、印度這四國的人均GDP對比,左上角顯示了圖例,將鼠標停留在某個點上,可以看到具體數據。4.1案例:四國宏觀經濟數據對比從人均GDP上來看,美國和英國這兩個發達國家基本接近,美國的增長勢頭強于英國。再次運行程序,選擇“gdp.json”,生成“gdp_compared.svg”圖形文件。同樣,可以生成4國人口數據對比圖。可以看出:中國的人口增速低于印度,但明顯高于美國和英國;2006年中國的GDP超過英國,與美國的差距也在逐漸縮小。4.1案例:四國宏觀經濟數據對比除列表之外,字典(dictionary)是另外一種最經常被用來處理數據集合的組合數據類型,二者經常一起使用。4.2字典列表中的單個元素是通過索引號(下標)來獲取的,如果多個列表之間的信息存在關聯,一般也是通過索引號來一一對應的。在第3章案例中,分別定義了3個列表來存儲不同項數(item_values)、不同項數對應的pi值(pi_values)以及不同項數對應的精確小數位數(accu_values),要查找某一項數對應的pi值和精確小數位數,需要先通過第一個列表來查找到索引號,然后根據索引號去第二個和第三個里列表查找。如果要改動某一個列表的順序,其他兩個列表必須跟著改變。4.2.1字典的表示那能不能把項數和pi值、精確小數位數存放在一起呢,找到某一項數,就能直接找到對應的pi值或精確小數位數。這種獲取信息的方式顯然更加靈活,在程序設計語言中,我們把這種方式稱為鍵值對(key-valuepair),這里的鍵就是項數,值就是pi值或精確小數位數。這種例子還有很多,比如用戶名—密碼,國家代碼—國家名稱,課程編碼—課程信息,學號—學生信息,工號—教師信息,英語單詞—含義及用法,等等。Python中把由若干個鍵值對構成的組合類型稱為字典。4.2.1字典的表示字典用花括號表示,不同的鍵值對之間用逗號分隔,鍵與值之間用冒號分隔。如下語句創建了一個存儲中國人口數據的字典:CHN={1960:667070000.0,2018:1392730000.0}該字典有兩個鍵值對,分別存放了中國1960年和2018年的人口數據,其中鍵代表年份,值代表人口數據。可以看到2018年中國的人口數據是1960年的兩倍多。字典中的鍵是唯一的,即不允許同一個鍵出現兩次,值則沒有限制。創建字典此外,鍵要求是可哈希的(hashable),可以是任意的不可修改的數據類型,包括數字、字符串和元組,值則沒有要求,可以是任意對象。上例中的鍵和值都是數字類型。字典的轉換函數dict()可以將二元組的列表轉換為字典,也可以通過關鍵字傳參的方式來賦值,比如:dict([('x',1),('y',2)])dict(x=1,y=2)返回結果都是{'x':1,'y':2},注意后一種方式在生成字典的時候,自動把參數名轉換為字符串。創建字典字典中的單個元素就是一個鍵值對,和列表不同的是,字典是無序的,每一個鍵值對并沒有出現的先后次序,因此無法通過索引號(下標)去訪問它們。但可以像查字典一樣,通過鍵去查找它的值,如下所示:<dict>[key]如果[key]不存在,會出現鍵錯誤(KeyError)。比如:CHN[1990],想查找1990年的中國人口數據,CHN中并沒有1990這個鍵,就會報錯。字典中的單個元素字典和列表一樣,是一種可以修改的數據類型,可以添加、修改或刪除某個元素。想要添加或修改某個元素,只要給<dict>[key]賦值就可以,如果[key]不存在,則為添加,否則就是修改,會覆蓋之前的值。如:CHN[1990]=1135185000.0CHN中沒有1990這個鍵,因而添加了一個鍵值對,添加后CHN的值為:{1960:667070000.0,1990:1135185000.0,2018:1392730000.0}記住字典是無序的,添加也不一定是添加在最后,可能出現在任何位置。字典中的單個元素由于字典和列表都是可以修改的數據類型,因此二者經常一起使用來存儲和處理數據。如下語句創建了一個存放人口數據的列表:values=[{"CountryCode":"CHN","CountryName":"China","Value":667070000.0,"Year":1960},{"CountryCode":"CHN","CountryName":"China","Value":1392730000.0,"Year":2018}]列表中每個元素都是一個字典,包括國家代碼、國家名稱、值和年份四個鍵。雖然列表中的每個元素可以是任意值,但在存儲和處理數據時,通常是同一種類型和結構的數據。進一步擴展,該列表可以存放世界不同國家不同年份的人口數據,我們既可以方便地查詢某個國家人口隨時間的變化,也可以方便地查詢某年不同國家人口的差異。字典的列表比較運算符、邏輯運算符、成員運算符也適用于字典,本節介紹成員運算符的使用。字典的成員運算符用來判斷某個鍵是否在字典中,比如:想從字典CHN中查詢中國1980年的人口數據,如果直接通過CHN[1980]來訪問,有可能因為鍵不存在而報錯,我們可以加一個判斷語句,如下所示:if1980inCHN:print(CHN[1980])如果1980存在,則輸出結果,如果不存在,什么也不輸出,程序也不會報錯。4.2.2字典的運算符和函數關于字典的內置函數,上一節介紹了dict()類型轉換函數,本節介紹len()函數。len()函數適用于序列,也適用于字典,返回的是元素的個數,也就是鍵值對的個數。但是我們并不能像列表那樣,把它用于for循環中,比如:foriinrange(len(CHN)):print(CHN[i])4.2.2字典的運算符和函數因為字典的元素無法通過索引號(下標)去訪問,CHN[i]中的i是鍵而不是索引號,所以會出現鍵錯誤。我們可以采用如下循環語句對字典中的元素進行處理:foreachinCHN:print("%4d\t%12.1f"%(each,CHN[each])循環變量each遍歷CHN中的每個鍵,CHN[each]就是每個鍵的值,在循環體內同時輸出鍵和值,分別按4位整數和12位小數(1位小數位)的格式輸出,結果如下:1960 667070000.02018 1392730000.04.2.2字典的運算符和函數本章案例中假設變量values存儲了是世界各國1960~2018年的人口數據,將中國、美國、英國、印度四國的人口數據找出來并存進各自字典的代碼如下:CHN,USA,GBR,IND={},{},{},{}#字典,key是年,value是值foreachinvalues:ifeach['CountryCode']=='CHN':

CHN[each['Year']]=each['Value']

continueifeach['CountryCode']=='USA':

USA[each['Year']]=each['Value']

continueifeach['CountryCode']=='GBR':

GBR[each['Year']]=each['Value']

continueifeach['CountryCode']=='IND':

IND[each['Year']]=each['Value']4.2.2字典的運算符和函數循環變量each遍歷values中的每個元素(對應每條數據的一個字典),如果發現它的鍵'CountryCode'的值是'CHN',也就是中國的數據,那么就向字典CHN中添加一個元素(鍵值對),鍵就是字典each中鍵'Year'的值,值就是each中鍵'Value'的值。clear()、copy()和pop()方法列表也有,其他方法均不同。get()方法用于獲取字典中的單個元素值,參數即為key,且比直接通過<dict>[key]的方式訪問要好,如果key不存在,也不會報錯,默認返回None,如果希望返回其他值,可以指定第二個參數。keys()、values()、items()方法的返回值均為可迭代對象,可以通過list()函數轉換成列表,分別存放字典的鍵列表、值列表、鍵值元組對列表。4.2.3字典的常用方法方法功能dict.clear()清空dict中的所有元素dict.copy()返回dict的一個復本dict.get(key,default=None)返回key對應的值,如果key在dict中不存在,返回defaultdict.items()返回dict的所有(key,value)元組對的可迭代對象dict.keys()返回dict的所有鍵的可迭代對象dict.pop(key)刪除并返回key對應的值,如果key在dict中不存在,出現鍵錯誤dict.update(dict2)把dict2的鍵值對加入dict,如果鍵重復則覆蓋dict.values()返回dict的所有值的可迭代對象讀取一個文本文件(比如一本小說),統計其中每個單詞出現的頻次,不考慮標點符號,單引號除外,比如“don’t”、“it’s”、“I’m”都是常用詞匯。輸出詞頻最高的n個單詞,n由用戶指定。【例4-1】詞頻統計【例4-1】詞頻統計將除單引號之外的所有標點符號替換為空格,再調用split()方法將文本進行分解,分解后的所有單詞存放在列表words中。構建一個字典counts來進行詞頻統計,鍵就是出現的單詞,值就是這個單詞出現的次數。遍歷words中的每一個單詞w,如果是第一次碰到w,那么給字典counts添加一個元素,counts[w]賦值為1;如果不是第一次碰到,counts[w]累加1。調用zip()函數生成了一個元組對的列表freq,這個元組對的第一個元素是值(頻次),第二個元素是鍵(單詞),那么調用sort()方法就可以按照頻次進行排序,指定參數reverse=True,即按降序排列。這樣,列表freq就對所有單詞按頻次進行了排序,可以輸出了。用戶輸入n的值之后,輸出freq中前n個元素,格式符“%-15s”表示輸出單詞時保留15位空間,且左對齊。運行程序,輸入要進行詞頻統計的文件名,比如:“little_women.txt”(小說《小婦人》),再輸入要輸出多少個詞頻最高的單詞,比如:25。【例4-1】詞頻統計看一看string庫中punctuation都包含哪些標點符號,嘗試在程序中不引入常量punctuation,直接用字符串來表示。試一試4.3集合本節將介紹最后一種數據類型:集合。Python中的集合與數學中的集合有很多共同之處。4.3.1集合的表示集合(set)和字典一樣,是無序的,但其中的元素并不是鍵值對,而是一個可哈希的值,且元素不重復,和字典中的鍵一樣。創建集合集合也是用花括號表示的,所以要創建一個空集合,不能用一對花括號來表示,那樣會被認為是空字典,只能通過類型轉換函數來創建。有兩種類型的集合,一種是可以修改的集合,另一種是不可修改的集合,類型轉換函數分別為set()和frozenset()。創建集合可以修改的集合類似列表,可以添加、刪除元素,不可修改的集合類似元組,不可以添加、刪除元素。注意:創建集合時,其中的元素不能重復,比如:s=set('cheese')結果s的值為{'h','e','c','s'}。集合中的單個元素集合與列表不同,它是無序的,因此無法通過索引號(下標)去訪問單個元素;集合又與字典不同,它沒有鍵,因此也無法通過鍵去訪問單個元素。我們只能通過成員運算符去判斷某個元素是否在集合中,或者通過循環迭代的方式逐一訪問其中的元素。4.3.2集合的運算符和函數除了成員運算符,比較運算符、邏輯運算符也適用于集合,除此之外,還有類似數學集合的集合運算符。比較運算符功能集合運算符功能==相等&交集!=不等|并集<=子集-差集或相對補集<

嚴格子集^對稱差集>=超集

>

嚴格超集

4.3.2集合的運算符和函數s是t的子集,t不是u的子集;t和u之間有交集,也有差集。注意:集合之間沒有連接運算符“+”,兩個集合的連接可以使用并集運算符。4.3.2集合的運算符和函數關于集合的內置函數,上一節介紹了set()和frozenset()兩個類型轉換函數,除此之外,len()函數也適用于集合,返回的也是元素的個數。和字典一樣,我們一般不把它用于for循環中,比如:foriinrange(len(s)):print(s[i])因為集合的元素無法通過索引號(下標)去訪問,會出現類型錯誤(TypeError)。4.3.3集合的常用方法方法功能s.add(obj)將obj添加至ss.clear()清空s中的所有元素s.copy()返回s的一個復本s.difference(t)返回s-ts.discard(obj)如果obj在s中,則刪除它ersection(t)返回s和t的交集s.issubset(t)如果s是t的子集,返回True,否則返回Falses.issuperset(t)如果s是t的超集,返回True,否則返回Falses.pop()刪除并返回s中任意一個對象s.remove(obj)從s中刪除obj,如果obj不在s中,出現鍵錯誤s.symmetric_difference(t)返回s和t的對稱差集s.union(t)返回s和t的并集s.update(t)將t的元素添加進s,如果元素重復則忽略4.3.3集合的常用方法add()、clear()、discard()、pop()、remove()、update()方法只適用于可以修改的set類型,不適用于不可修改的frozenset類型。clear()、copy()和pop()方法字典也有,其他方法均不同。4.4JSON文件本節介紹常用的數據文件之一:JSON文件。JSON(JavaScriptObjectNotation)是一種通用的輕量級的數據交換格式。JSON具有數據格式簡單、讀寫方便等優點,很多網站都會用到JSON格式來進行數據的傳輸和交換。用Python處理JSON格式的數據,首先要實現JSON格式與Python數據類型的相互轉換。JSON的數據結構有兩種:對象結構和數組結構,分別對應Python的字典和列表,因此在Python中使用JSON非常簡單,可以將JSON格式視為由列表和字典的自由嵌套組成的數據集合。4.4.1JSON格式4.4.1JSON格式Python數據類型說明JSON數據類型說明字典鍵值對,花括號對象鍵值對,花括號列表、元組方括號、圓括號數組方括號字符串雙引號、單引號字符串雙引號整型、浮點型

數字

布爾型True、False布爾型true、false空對象None空對象null以我們從DataHub上下載的世界各國1960年以來的人口、GDP和人均GDP數據集為例,其數據格式為:[{"CountryCode":"ARB","CountryName":"ArabWorld","Value":222.688851118821,"Year":1968},{"CountryCode":"ARB","CountryName":"ArabWorld","Value":238.909677072309,"Year":1969},…,{"CountryCode":"ZWE","CountryName":"Zimbabwe","Value":1029.07664867845,"Year":2016}]Python提供了json標準庫對JSON格式進行編碼和解碼,引入它之后就可以調用其中的函數來進行操作。4.4.2JSON庫函數功能函數功能dump(obj,f)解析obj,寫入文件對象fload(f)讀取文件對象f,解析為Python對象dumps(obj)解析obj為JSON字符串loads()解析JSON字符串為Python對象dumps()和loads()互為解析將城市的緯度和經度存入JSON文件。創建名為“location_on_earth.json”的文件,存放北京、香港、上海、華盛頓特區4個城市的緯度和經度數據,如下所示:[{"City":"Beijing","Latitude":39.93,"Longitude":116.46},{"City":"Hongkong","Latitude":22.28,"Longitude":114.13},{"City":"Shanghai","Latitude":31.23,"Longitude":121.45},{"City":"WashingtonDC","Latitude":38.94,"Longitude":-77.05}]【例4-2】修改例2-2,從JSON文件中獲取數據【例4-2】修改例2-2,從JSON文件中獲取數據以只讀方式打開文件,調用json庫的load()函數讀取文件的內容存入points中。對JSON文件中存放的所有城市進行循環迭代,判斷是否是起點或終點城市。如果是起點城市,給起點的緯度和經度t1、g1賦值,如果是終點城市,給終點的緯度和經度t2、g2賦值。計算兩點之間的距離后輸出。這里要解決的一個關鍵問題是:如果用戶輸入的城市不在JSON文件中該如何處理?如果不做任何處理,程序會報錯,因為t1、g1、t2、g2沒有被賦值。只要被賦值了,就說明JSON文件中有這個城市。因此,給t1和t2賦初值為0,如果起點和終點在JSON文件中都存在,那么t1andt2的結果就為True,計算距離并輸出。如果有一個城市在JSON文件中不存在,那么t1andt2的結果就為False,執行else分支。在else分支中,進一步判斷是起點城市還是終點城市沒找到,并給用戶提示信息。【例4-2】修改例2-2,從JSON文件中獲取數據運行程序,對不同情況進行測試。【例4-2】修改例2-2,從JSON文件中獲取數據本章案例要從存放了世界各國1960年以來的人口、GDP和人均GDP的JSON文件中讀取數據,首先要打開文件對話框讓用戶選擇相應的數據文件,代碼如下:fromtkinter.filedialogimportaskopenfilename#指定文件類型file_name=askopenfilename(filetype=[(‘JSONfiles’,‘*.json’)])f=open(file_name,'r')values=json.load(f)f.close()4.4.2JSON庫以只讀方式打開文件后,調用json庫中的load()函數讀取數據并存放在變量values中,關閉文件。filedialog包中的askopenfilename()函數可以指定文件類型參數,也就是在打開文件對話框中限定文件類型,這個參數的值是一個列表,也就是可以限定多種文件類型,每種文件類型用一個二元組表示,二元組的第一個元素是表示文件類型的字符串,第二個元素是指定文件類型的格式,比如“*.json”表示后綴名為“json”的文件。這里,我們只限定了一種文件類型,因此列表里只有一個二元組。4.4.2JSON庫至此,本章案例除數據可視化部分已完成,將程序文件保存為ch04.py,運行程序,如果有錯誤則進行修正。調用print()函數輸出結果。試一試pygal第三方庫的主要功能也是數據可視化,可以用來生成可縮放的矢量圖形文件(ScalableVectorGraphics,SVG),引入前也需要通過pip工具進行安裝。4.5編程實踐:Pygal芝加哥期權交易所VIX指數用來衡量標普500指數(S&P500)在未來30天的隱含波動率,該指數也被稱為恐慌指數,反映市場情緒和預期股市未來波動性。我們從DataHub上搜集并下載了VIX數據集,包含2004年1月2日——2020年9月4日每日收盤、最高、最低和開盤的數據,并將數據文件命名為“vix_daily.json”,其格式和內容如下:[{"Date":"2004-01-02","VIXClose":18.22,"VIXHigh":18.68,"VIXLow":17.54,"VIXOpen":17.96},…,{"Date":"2020-09-04","VIXClose":30.75,"VIXHigh":38.28,"VIXLow":29.5,"VIXOpen":34.62}]【例4-3】生成VIX指數時間序列圖【例4-3】生成VIX指數時間序列圖橫坐標是日期,縱坐標選取收盤數據。將dates和close賦為空列表,將每天的數據添加進這兩個列表。由于數據較多,我們將每隔5天(一周)的數據存入列表。用Bar類來創建一個柱狀圖的對象實例bar,然后給bar的x軸賦值為dates,再設置x軸的主刻度的步長為26,也即是每26個5天顯示一個標簽。調用bar的add()方法添加y軸的數據,即close。給bar的圖標題、x軸的標題和y軸的標題分別賦值。調用bar的render_to_file()方法生成圖形文件。運行程序,找到生成的VIX時間序列圖。可以看到,橫坐標的日期旋轉了-45度顯示,如果不旋轉,日期標簽會相互交叉,無法全部顯示出來。顯示出來的數據是每隔5天,x軸的主刻度是每隔26*5天。【例4-3】生成VIX指數時間序列圖【例4-4】本章案例的實現用Line類來創建一個折線圖的對象實例line,然后給line的x軸賦值,即為年份,從CHN、USA、GBR、IND任意一個字典中獲取鍵列表即可,再設置x軸的主刻度的步長為2,也即是每2年顯示一個標簽。調用line的add()方法添加y軸的數據,包括CHN、USA、GBR、IND四個字典的值列表。給line的x軸的標題賦值為“year”,再給y軸的標題賦值,最后調用line的render_to_file()方法來生成一個SVG圖形文件,并給出提示信息。由于本例對人口、GDP和人均GDP的數據集通用,y軸的標題和生成的文件名對于不同的數據集有所不同。首先通過file_name獲得文件的路徑和名稱,調用字符串的split()方法按照路徑分隔符“/”分解,取出最后一個字串,即文件名稱,比如“gdp_pcap.json”;再次調用split()方法按照分隔符“.”分解,取

溫馨提示

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

評論

0/150

提交評論