歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux綜合 >> Linux資訊 >> 更多Linux

第五章 Python數據結構

  第五章 Python數據結構 last edited 2 months ago by panjy 本章更詳細地討論一些已經講過的數據類型的使用,並引入一些新的類型。 5.1 列表 列表數據類型還有其它一些方法。下面是列表對象的所有方法: insert(i, x) ---- 在指定位置插入一項。第一自變量是要在哪一個元素前面插入,用下 標表示。例如,a.insert(0, x)在列表前面插入,a.insert(len(a), x)等價於a.append(x) 。 append(x) ---- 等價於a.insert(len(a), x) index(x) ---- 在列表中查找值x然後返回第一個值為x的元素的下標。沒有找到時出錯。 remove(x) ---- 從列表中刪去第一個值為x的元素,找不到時出錯。 sort() ---- 對列表元素在原位排序。注意這個方法改變列表,而不是返回排序後的列表。 reverse() ---- 把列表元素反序。改變列表。 count(x) ---- 返回x在列表中出現的次數。   下例使用了所有的列表方法: >>> a = [66.6, 333, 333, 1, 1234.5] >>> print a.count(333), a.count(66.6), a.count('x') 2 1 0 >>> a.insert(2, -1) >>> a.append(333) >>> a [66.6, 333, -1, 333, 1, 1234.5, 333] >>> a.index(333) 1 >>> a.remove(333) >>> a [66.6, -1, 333, 1, 1234.5, 333] >>> a.reverse() >>> a [333, 1234.5, 1, 333, -1, 66.6] >>> a.sort() >>> a [-1, 1, 66.6, 333, 333, 1234.5] 5.1.1 函數程序設計工具 Python中有一些函數程序設計風格的東西,例如前面我們看到的lambda形式。關於列表有 三個非常有用的內置函數:filter(), map()和redUCe()。 “filter(函數, 序列)”返回一個序列(盡可能與原來同類型),序列元素是原序列中由 指定的函數篩選出來的那些,篩選規則是“函數(序列元素)=true”。filter()可以用來取出 滿足條件的子集。例如,為了計算一些素數: >>> def f(x): return x % 2 != 0 and x % 3 != 0 ... >>> filter(f, range(2, 25)) [5, 7, 11, 13, 17, 19, 23] “map(函數,序列)”對指定序列的每一項調用指定的函數,結果為返回值組成的列表。map() 可以對序列進行隱式循環。例如,要計算三次方,可用: >>> def cube(x): return x*x*x ... >>> map(cube, range(1, 11)) [1, 8, 27, 64, 125, 216, 343, 512, 729, 1000] 可以有多個序列作為自變量,這時指定的函數必須也有相同個數的自變量,函數從每個序 列分別取出對應元素作為自變量進行調用(如果某個序列比其它的短則取出的值是None)。 如果指定的函數是None,map()把它當成一個返回自己的自變量的恆同函數。在函數用None的 情況下指定多個序列可以把多個序列搭配起來,比如“map(None, list1, list2)”可以把兩 個列表組合為一個成對值的列表。見下例: >>> seq = range(8) >>> def square(x): return x*x ... >>> map(None, seq, map(square, seq)) [(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25), (6, 36), (7, 49)] “reduce(函數, 序列)”用來進行類似累加這樣的操作,這裡的函數是一個兩個子變量的 函數,reduce()先對序列的前兩項調用函數得到一個結果,然後對結果和序列下一項調用函 數得到一個新結果,如此進行到序列尾部。例如,要計算1到10的和: >>> def add(x,y): return x+y ...


>>> reduce(add, range(1, 11)) 55 如果序列中只有一個值則返回這個值,序列為空時會產生例外。可以指定第三個自變量作 為初始值。有初始值時對空序列函數將返回初始值,否則函數先對初始值和序列第一項作用 ,然後對結果和序列下一項作用,如此進行到序列尾。例如: >>> def sum(seq): ... def add(x,y): return x+y ... return reduce(add, seq, 0) ... >>> sum(range(1, 11)) 55 >>> sum([]) 0 5.2 del語句 上面我們看到,列表的remove()方法可以從列表中刪去某個取值的項,我們還可以用del 語句來刪除指定下標的項。也可以用del語句從列表中刪除一個片斷(前面我們是用給片斷賦 空列表的辦法刪除片斷的)。例如: >>> a [-1, 1, 66.6, 333, 333, 1234.5] >>> del a[0] >>> a [1, 66.6, 333, 333, 1234.5] >>> del a[2:4] >>> a [1, 66.6, 1234.5] del也可以用來刪除整個變量,例如: >>> del a 變量刪除以後再引用該變量就會出錯(除非又給它賦值了)。後面我們還會看到del的其 它一些應用。 5.3 序表和序列 我們看到列表和字符串有許多共同點,例如,下標和片斷運算。它們都屬於序列數據類型 。因為Python是一個正在不斷發展的語言,以後還可能會加入其它的序列數據類型。現在還 有一種標准的序列數據類型,稱為序表(tuple)。 序表由一系列值用逗號分隔而成,例如: >>> t = 12345, 54321, 'hello!' >>> t[0] 12345 >>> t (12345, 54321, 'hello!') >>> # 序表允許嵌套: ... u = t, (1, 2, 3, 4, 5) >>> u ((12345, 54321, 'hello!'), (1, 2, 3, 4, 5)) 輸出的序表總是用括號包圍,這樣可以保證嵌套序表得以正確解釋。輸入時可以有括號也 可以沒有括號,當經常是必須有括號(如果序表是一個大表達式的一部分)。 序表有許多用處,例如,(x,y)坐標對,數據庫中的職工紀錄,等等。序表與字符串一 樣是不可變的:不允許對序表的某一項賦值。 生成序表時對0項或1項的序表有特殊的規定:空序表用一對空括號表示;只有一項的序表 用一個之後面跟一個抖好表示(指把這個值放在括號內是不夠的)。這樣寫不夠美觀,但很 有效。例如: >>> empty = () >>> singleton = 'hello', # <-- note trailing comma >>> len(empty) 0 >>> len(singleton) 1 >>> singleton ('hello',) 語句t = 12345, 54321, 'hello!'是序表打包的一個實例:12345, 54321和'hello!'這些 值被打包進了一個序表中。相反的操作也是允許的,例如: >>> x, y, z = t 這叫做序表解包。序表解包要求等號左邊的變量個數等於序表的長度。注意多重賦值只是 序表打包和序表解包的聯合使用。有時也對列表進行類似操作,即列表解包。只要把各變量 寫成一個列表就可以進行解包: >>> a = ['spam', 'eggs', 100, 1234] >>> [a1, a2, a3, a4] = a 5.4 字典 Python內置的另一個有用的數據類型是字典。字典在其它語言中有時被稱為“關聯記憶” 或“關聯數組”。字典不象序列,它不是用在一個范圍之內的數字下標來索引,而是用鍵值 來索引,鍵值可以是任何不可變類型。字符串和數值總可以作鍵值。如果序表只包含字符串 、數值或序表則序表也可以作鍵值使用。列表不能用作鍵值,因為列表可以用其append()方 法就地改變值。 最好把字典看成是一系列未排序的“鍵值:值”的集合,在同一字典內鍵值是互不相同的 。一對空大括號產生一個空字典:{}。在大括號內加入用逗號分開的“鍵值:值”對可以在 字典內加入初始的鍵值和值對,字典在輸出時也是這樣顯示的。對字典的主要操作是以某個 鍵值保存一個值,以及給定鍵值後查找對應的值。也可以用del刪除某個鍵值:值對。如果用 一個已有定義的鍵值保存某個值則原來的植被遺忘。用不存在的鍵值去查找會出錯。

字典對象的keys()方法返回字典中所有鍵值組成的列表,次序是隨機的。需要排序時只要 對返回的鍵值列表使用sort()方法。為了檢查某個鍵值是否在字典中,使用字典的has_key() 方法。 下面是字典使用的一個簡單例子: >>> tel = {'jack': 4098, 'sape': 4139} >>> tel['guido'] = 4127 >>> tel {'sape': 4139, 'guido': 4127, 'jack': 4098} >>> tel['jack'] 4098 >>> del tel['sape'] >>> tel['irv'] = 4127 >>> tel {'guido': 4127, 'irv': 4127, 'jack': 4098} >>> tel.keys() ['guido', 'irv', 'jack'] >>> tel.has_key('guido') 1 5.5 條件的進一步討論 在while語句和if語句中使用的條件除了可以使用比較之外還可以包含其它的運算符。比 較運算符“in”和“not in”可以檢查一個值是否在一個序列中。運算符“is”和“is not ”比較兩個對象是否恰好是同一個對象,這只對象列表這樣的可變對象有意義。所有比較運 算優先級相同,而比較運算的優先級比所有數值運算優先級低。 比較允許連寫,例如,a < b == c檢查是否a小於等於b而且b等於c。 比較可以用邏輯運算符and和or連接起來,比較的結果(或其它任何邏輯表達式)可以用not 取反。邏輯運算符又比所有比較運算符低,在邏輯運算符中,not優先級最高,or的優先級最 低,所以“A and not B or C”應解釋為“(A and (not B)) or C”。當然,可以用括號來 表示所需的組合條件。 邏輯運算符and和or稱為“短路”運算符:運算符兩側的表達式是先計算左邊的,如果左 邊的結果已知則整體結果已知就不再計算右邊的表達式。例如,如果A和C為真而B為假則“A and B and C”不會計算表達式C。一般地,當短路運算符的運算結果不是用作邏輯值的時候 返回的是最後求值的那個表達式的值。 可以把比較或其它邏輯表達式的結果賦給一個變量。例如: >>> string1, string2, string3 = '', 'Trondheim', 'Hammer Dance' >>> non_null = string1 or string2 or string3 >>> non_null 'Trondheim' 注意Python和C不同,表達式中不能進行賦值。 5.6 序列與其它類型的比較 序列對象可以和其它同序列類型的對象比較。比較使用字典序:先比較最前面兩項,如果 這兩項不同則結果可以確定;如果這兩項相同,就比較下面的兩項,如此下去,直到有一個 序列到頭為止。如果某兩項本身也是同類型的序列,則進行遞歸的字典序比較。如果兩個序 列的所有各項都相等,則這兩個序列相等。如果一個序列是另一個序列的一個初始子序列, 短的一個是較小的一個。字符串的字典序比較按各個字符的ASCII次序進行。下面是一些序列 比較的實例: (1, 2, 3) < (1, 2, 4) [1, 2, 3] < [1, 2, 4] 'ABC' < 'C' < 'Pascal' < 'Python' (1, 2, 3, 4) < (1, 2, 4) (1, 2) < (1, 2, -1) (1, 2, 3) = (1.0, 2.0, 3.0) (1, 2, ('aa', 'ab')) < (1, 2, ('abc', 'a'), 4) 注意不同類型的對象比較目前也是合法的。結果是確定的但卻沒有什麼意義:不同類型是 按類型的名字排序的。所以,列表(list)總是小於字符串(string),字符串總是小於序 表(tuple),等等。但是程序中不能依賴這樣的比較規則,語言實現可能會改變。不同的數 值類型可以按數值來比較,所以0等於0.0,等等。



>>> non_null 'Trondheim' 注意Python和C不同,表達式中不能進行賦值。 5.6 序列與其它類型的比較 序列對象可以和其它同序列類型的對象比較。比較使用字典序:先比較最前面兩項,如果 這兩項不同則結果可以確定;如果這兩項相同,就比較下面的兩項,如此下去,直到有一個 序列到頭為止。如果某兩項本身也是同類型的序列,則進行遞歸的字典序比較。如果兩個序 列的所有各項都相等,則這兩個序列相等。如果一個序列是另一個序列的一個初始子序列, 短的一個是較小的一個。字符串的字典序比較按各個字符的ASCII次序進行。下面是一些序列 比較的實例: (1, 2, 3) < (1, 2, 4) [1, 2, 3] < [1, 2, 4] 'ABC' < 'C' < 'Pascal' < 'Python' (1, 2, 3, 4) < (1, 2, 4) (1, 2) < (1, 2, -1) (1, 2, 3) = (1.0, 2.0, 3.0) (1, 2, ('aa', 'ab')) < (1, 2, ('abc', 'a'), 4) 注意不同類型的對象比較目前也是合法的。結果是確定的但卻沒有什麼意義:不同類型是 按類型的名字排序的。所以,列表(list)總是小於字符串(string),字符串總是小於序 表(tuple),等等。但是程序中不能依賴這樣的比較規則,語言實現可能會改變。不同的數 值類型可以按數值來比較,所以0等於0.0,等等。



'ABC' < 'C' < 'Pascal' < 'Python' (1, 2, 3, 4) < (1, 2, 4) (1, 2) < (1, 2, -1) (1, 2, 3) = (1.0, 2.0, 3.0) (1, 2, ('aa', 'ab')) < (1, 2, ('abc', 'a'), 4) 注意不同類型的對象比較目前也是合法的。結果是確定的但卻沒有什麼意義:不同類型是 按類型的名字排序的。所以,列表(list)總是小於字符串(string),字符串總是小於序 表(tuple),等等。但是程序中不能依賴這樣的比較規則,語言實現可能會改變。不同的數 值類型可以按數值來比較,所以0等於0.0,等等。



Copyright © Linux教程網 All Rights Reserved