天天看點

Python提供的一些相當實用而靈活的通用資料結構

拙劣的程式員擔心代碼。好的程式員擔心資料結構及它們的關系。

——林納斯•托瓦茲

本章介紹Python的基本資料類型和資料結構,它們按照如下方式組織。

基本資料類型

3.1節介紹整數、浮點數和字元串等基本資料類型。

基本資料結構

3.2節介紹Python的基本資料結構(例如List對象)并闡述控制結構、函數式程式設計範型以及匿名函數。

本章的主旨是提供Python資料類型和結構細節的一般介紹。如果您有其他程式設計語言(如C或者Matlab)的背景,應該能夠輕松地掌握Python使用方法帶來的差異。本章介紹的主題是後續章節的重要基礎,涵蓋了以下資料類型與結構。

Python提供的一些相當實用而靈活的通用資料結構

3.1 基本資料類型

Python是一種動态類型的語言,這意味着,Python解釋程式在運作時推斷對象的類型。C等編譯語言通常是靜态類型語言,在這類語言中,對象類型必須在編譯之前與對象綁定[1]。

3.1.1 整數

最基本的資料類型是整數int:

In [1]: a = 10
        type(a)
Out[1]: int      

内建函數type為所有使用标準和内建類型的對象、新建立的類及對象提供類型資訊。在後一種情況下,提供的資訊取決于程式員存儲在類中的描述。有一種說法:“在Python中,一切都是對象。”這意味着,即使我們剛剛定義的簡單對象int也有内建方法。例如,您可以調用bit_length方法,獲得表現整數對象所需的位數:

In [2]: a.bit_length()
Out[2]: 4      

您将會看到,我們為該對象所賦的整數值越大,需要的位數就越多:

In [3]: a = 100000
        a.bit_length()
Out[3]: 17      

一般來說,這類方法很多,很難記住所有類和對象的所有方法。進階Python環境(如IPython)提供Tab鍵完成功能,以顯示對象連接配接的所有方法。您隻需要輸入對象名和一個點(如a.)然後按下Tab鍵,就會提供一組可以在該對象上調用的方法。也可以使用Python内建函數dir顯示任何對象屬性和方法的完整清單。

Python的特殊性之一是整數可以任意大。例如,考慮天文數字10100。Python處理這樣大的數毫無問題,這從技術上說是一個很“長”的對象:

In [4]: googol = 10 ** 100
        googol
Out[4]:  1000000000000000000000000000000000000000000000000000000000000
        000000000000000000000000000000000000000
In [5]: googol.bit_length()
Out[5]: 333      

大整數

Python整數可以為任意大。解釋程式簡單地使用所需的位/位元組數就可表現數值。

整數的算術運算也很容易實作:

In [6]: 1 + 4
Out[6]: 5

In [7]: 1 / 4
Out[7]: 0.25

In [8]: type(1 / 4)
Out[8]: float      

3.1.2 浮點數

為了讓上一個表達式傳回所需的值——0.25[2],我們必須在浮點(float)對象上操作,這很自然地把我們帶到下一種基本資料類型。在整數值上加一個點比如1.或者1.0,會導緻Python将該對象解釋為浮點數。涉及浮點數的表達式通常也必須傳回一個浮點對象[3]:

In [9]: 1.6 / 4
Out[9]: 0.4
In [10]: type (1.6 / 4)
Out[10]: float      

浮點數與通常不精确的實數計算機表現形式關系更大,取決于所采用的具體技術方法。為了說明其中的含義,我們定義另一個浮點對象b,這種浮點對象在内部總是隻表現為某種精度。将b加上0.1時,這一點變得很明顯:

In [11]: b = 0.35
         type(b)
Out[11]: float

In [12]: b + 0.1
Out[12]: 0.44999999999999996      

出現以上結果的原因是浮點數在計算機内部以二進制形式表示;也就是說,十進制數n(0<n<1)表現為如下形式:

Python提供的一些相當實用而靈活的通用資料結構

對于某些浮點數,二進制表現形式可能包含大量元素甚至是一個無限系列。但是,考慮到用于表達這種數值的位數是固定的——也就是表現系列中的項目固定,是以結果是不精确的。其他數值可以完整表現,是以在可用位數有限時也可以精确地被存儲。考慮如下例子:

In [13]: c = 0.5
         c.as_integer_ratio()
Out[13]: (1, 2)      

0.5可以精确儲存,因為它具備精确(有限)的二進制表示:0.5=1/2。但是,b=0.35和預期的實數0.35=7/20不同:

In [14]: b.as_integer_ratio()
Out[14]: (3152519739159347, 9007199254740992)      

精度取決于表示數值所用的位數。一般來說,Python運作的所有平台使用IEEE 754雙精度标準(64位)作為内部表示,這相當于15位數字的相對精度。

由于這個主題在金融應用領域中很重要,是以有時候必須確定數值的精确(至少盡可能達到最佳)。例如,在加總一組數量很多的數值時,這個問題就可能很重要。在這種情況下,某個種類或者幅度的表示誤差可能彙聚起來,進而造成和基準值的顯著偏差。

decimal子產品為浮點數提供了任意精确度的對象,以及使用這些數值時處理精度問題的多個選項:

In [15]: import decimal
         from decimal import Decimal

In [16]: decimal.getcontext()
Out[16]: Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, 
         Emax=999999, capitals=1, clamp=0, flags=[], traps=
         [InvalidOperation, DivisionByZero, Overflow])

In [17]: d = Decimal(1) / Decimal (11)
d
Out[17]: Decimal('0.09090909090909090909090909091')      

您可以改變Context對象的各個屬性值,進而改變表示的精度:

In [18]: decimal.getcontext().prec = 4❶

In [19]: e = Decimal(1) / Decimal (11)
         e
Out[19]: Decimal('0.09091')

In [20]: decimal.getcontext().prec = 50❷

In [21]: f = Decimal(1) / Decimal (11)
         f
Out[21]: Decimal('0.090909090909090909090909090909090909090909090909091')      

❶ 精度低于預設值。

❷ 精度高于預設值。

如果有必要,精度可以這樣按照具體的問題進行調整,人們可以使用不同精度的浮點對象進行運算:

In [22]: g = d + e + f
         g
Out[22]: Decimal('0.27272818181818181818181818181909090909090909090909')      

任意精度浮點數

decimal子產品可提供任意精度浮點數對象。在金融領域中,確定高精度、超出64位雙精度标準有時是必要的。

3.1.3 布爾值

在程式設計中,比較或者邏輯表達式(如4 > 3, 4.5 <= 3.25 或 (4 > 3) and (3 > 2))得到的輸出為True或者False,這是兩個重要的Python關鍵字。其他重要的關鍵字有def、for和if等。Python的關鍵字清單可以在keyword子產品中找到:

In [23]: import keyword

In [24]: keyword.kwlist
Out[24]: ['False',
          'None',
          'True',
          'and',
          'as',
          'assert',
          'async',
          'await',
          'break',
          'class',
          'continue',
          'def',
          'del',
          'elif',
          'else',
          'except',
          'finally',
          'for',
          'from',
          'global',
          'if',
          'import',
          'in',
          'is',
          'lambda',
          'nonlocal',
          'not',
          'or',
          'pass',
          'raise',
          'return',
          'try',
          'while',
          'with',
          'yield']      

True和Flase的資料類型為bool,表示“布爾值”(Boolean Value)。将Python的比較運算符應用到相同操作數時結果為布爾對象:

In [25]: 4 > 3❶
Out[25]: True

In [26]: type(4 > 3)
Out[26]: bool

In [27]: type(False)
Out[27]: bool

In [28]: 4 >= 3❷
Out[28]: True

In [29]: 4 < 3❸
Out[29]: False

In [30]: 4 <= 3❹
Out[30]: False

In [31]: 4 == 3❺
Out[31]: False

In [32]: 4 != 3❻
Out[32]: True      

❶ 大于。

❷ 大于或等于。

❸ 小于。

❹ 小于或等于。

❺ 等于。

❻ 不等于。

邏輯運算往往應用到布爾對象上,然後得出另一個布爾對象:

In [33]: True and True
Out[33]: True

In [34]: True and False
Out[34]: False

In [35]: False and False
Out[35]: False

In [36]: True or True
Out[36]: True

In [37]: True or False
Out[37]: True

In [38]: False or False
Out[38]: False

In [39]: not True
Out[39]: False

In [40]: not False
Out[40]: True      

當然,兩類運算符往往組合使用:

In [41]: (4 > 3) and (2 > 3)
Out[41]: False

In [42]: (4 == 3) or (2 != 3)
Out[42]: True

In [43]: not (4 != 4)
Out[43]: True

In [44]: (not (4 != 4)) and (2 == 3)
Out[44]: False      

布爾值的重要應用領域之一是通過其他Python關鍵字(如if或while,本章後面将有更多示例)控制代碼流程:

In [45]: if 4 > 3: ❶
              print('condition true') ❷
         condition true
In [46]: i = 0 ❸
         while i < 4: ❹
             print('condition true, i = ', i) ❺
             i += 1 ❻
         condition true, i = 0
         condition true, i = 1
         condition true, i = 2
         condition true, i = 3      

❶ 如果條件為真,執行以下代碼。

❷ 如果條件為真,執行這段代碼。

❸ 将參數i初始化為0。

❹ 隻要條件為0,就執行并重複以下代碼。

❺ 列印文本和參數i的值。

❻ 将參數增加1;i += 1與i = i + 1等價。

從數值上講,Python為False指派0,為True指派1。當通過bool()函數将數值轉換成bool對象時,0值轉換成False,其他所有值都轉換為True:

In [47]: int(True)
Out[47]: 1

In [48]: int(False)
Out[48]: 0

In [49]: float(True)
Out[49]: 1.0

In [50]: float(False)
Out[50]: 0.0

In [51]: bool(0)
Out[51]: False

In [52]: bool(0.0)
Out[52]: False

In [53]: bool(1)
Out[53]: True

In [54]: bool(10.5)
Out[54]: True

In [55]: bool(-2)
Out[55]: True      

3.1.4 字元串

既然我們已經可以表示自然和浮點數,現在就可以轉向文本了。Python中表示文本的基本資料類型是字元串——str,字元串對象有一些真正實用的内建方法。實際上,Python通常被視為處理任何類型、任何尺寸文本檔案的很好選擇。字元串對象通常由單引号或者雙引号定義或者使用str()函數轉換而來(也就是使用對象的标準或者使用者定義的字元串表示):

In [56]: t = 'this is a string object'      

舉個内建方法的例子,您可以将對象中的第一個詞改為首字母大寫:

In [57]: t.capitalize()
Out[57]: 'This is a string object'      

也可以将字元串拆分成單個詞,以獲得包含所有單詞的清單對象:

In [58]: t.split()
Out[58]: ['this', 'is', 'a', 'string', 'object']      

您還可以搜尋一個單詞,如果搜尋成功,就可以得到該詞第一個字母的位置(即索引值):

In [59]: t.find('string')
Out[59]: 10      

如果這個單詞不在字元串對象中,該方法傳回-1:

In [60]: t.find('Python')
Out[60]: -1      

替換字元串中的字元是典型的任務,可以用replace()方法簡單地完成:

In [61]: t.replace(' ', '|')
Out[61]: 'this|is|a|string|object'      

字元串“剝離”(stripping)操作——删除某些前導或者字尾字元也是必要的:

In [62]: 'http://www.python.org'.strip('htp:/')
Out[62]: 'www.python.org'      

表3-1列出了字元串對象的一些實用方法。

Python提供的一些相當實用而靈活的通用資料結構

Unicode字元串

Python 2.7(本書第1版使用)到Python 3.7(本書第2版使用)的根本變化之一是字元串對象的編碼與解碼方法,以及Unicode的引入。本章不介紹這方面的細節;本書主要處理數值資料和包含英語單詞的标準字元串,這種忽略似乎是合理的。

3.1.5 題外話:列印和字元串替換

列印字元串對象或者其他Python對象的字元串表示,通常由print()函數完成:

In [63]: print('Python for Finance') ❶
         Python for Finance

In [64]: print(t) ❷
         this is a string object

In [65]: i = 0
         while i < 4:
             print(i) ❸
             i += 1
         0
         1
         2
         3
In [66]: i = 0
         while i < 4:
             print(i, end='|') ❹
             i += 1
         0|1|2|3|      

❶ 列印一個str對象。

❷ 列印變量名引用的字元串對象。

❸ 列印整數對象的字元串表示。

❹ 指定列印的結束符,預設為前面見到的換行符(\n)

Python提供了強大的字元串替換運算。我們可以采用舊方法通過%字元,也可以采用通過花括号({})和format()函數的新方法。兩種方法在實踐中都适用。本節無法提供所有選項的說明,但以下代碼片段可以展示一些重要的選項。首先是舊方法:

In [67]: 'this is an integer %d' % 15 ❶
Out[67]: 'this is an integer 15'

In [68]: 'this is an integer %4d' % 15 ❷
Out[68]: 'this is an integer 15'

In [69]: 'this is an integer %04d' % 15 ❸
Out[69]: 'this is an integer 0015'

In [70]: 'this is a float %f' % 15.3456 ❹
Out[70]: 'this is a float 15.345600'

In [71]: 'this is a float %.2f' % 15.3456 ❺
Out[71]: 'this is a float 15.35'

In [72]: 'this is a float %8f' % 15.3456 ❻
Out[72]: 'this is a float 15.345600'

In [73]: 'this is a float %8.2f' % 15.3456 ❼
Out[73]: 'this is a float 15.35'

In [74]: 'this is a float %08.2f' % 15.3456 ❽
Out[74]: 'this is a float 00015.35'

In [75]: 'this is a string %s' % 'Python' ❾
Out[75]: 'this is a string Python'

In [76]: 'this is a string %10s' % 'Python' ❿
Out[76]: 'this is a string Python'      

❶ 整數對象替換。

❷ 固定數量的字元

❸ 必要時加上前導0。

❹ 浮點數對象替換。

❺ 固定小數位數。

❻ 固定數量字元(以及填充的小數位數)。

❼ 固定數量字元和小數位數…

❽ 必要時加上前導0。

❾ 字元串對象替換。

❿ 固定字元數。

下面是同樣的例子,但用新方法實作。注意某些位置輸出的細微差别:

In [77]: 'this is an integer {:d}'.format(15)
Out[77]: 'this is an integer 15'

In [78]: 'this is an integer {:4d}'.format(15)
Out[78]: 'this is an integer 15'

In [79]: 'this is an integer {:04d}'.format(15)
Out[79]: 'this is an integer 0015'

In [80]: 'this is a float {:f}'.format(15.3456)
Out[80]: 'this is a float 15.345600'

In [81]: 'this is a float {:.2f}'.format(15.3456)
Out[81]: 'this is a float 15.35'

In [82]: 'this is a float {:8f}'.format(15.3456)
Out[82]: 'this is a float 15.345600'

In [83]: 'this is a float {:8.2f}'.format(15.3456)
Out[83]: 'this is a float 15.35'

In [84]: 'this is a float {:08.2f}'.format(15.3456)
Out[84]: 'this is a float 00015.35'

In [85]: 'this is a string {:s}'.format('Python')
Out[85]: 'this is a string Python'

In [86]: 'this is a string {:10s}'.format('Python')
Out[86]: 'this is a string Python '      

字元串替換在多次列印更新的資料時特别有用,例如在while循環中:

In [87]: i = 0
         while i < 4:
             print('the number is %d' % i)
             i += 1
         the number is 0
         the number is 1
         the number is 2
         the number is 3
In [88]: i = 0
         while i < 4:
             print('the number is {:d}'.format(i))
             i += 1
         the number is 0
         the number is 1
         the number is 2
         the number is 3      

3.1.6 題外話:正規表達式

正規表達式是處理字元串對象的一個強大工具。Python在re子產品中提供了這個功能:

In [89]: import re      

假定您現在面對一個大的文本檔案,例如逗号分隔值(CSV)檔案,其中包含了某些事件序列和相應的日期-時間資訊。日期-時間資訊多半以Python無法直接解釋的格式提供。然而,日期-時間資訊通常可以通過正規表達式描述。考慮如下的字元串對象,它包含3個日期-時間元素、3個整數和3個字元串。注意,3個引号可以定義多行字元串:

In [90]: series = """
         '01/18/2014 13:00:00', 100, '1st';
         '01/18/2014 13:30:00', 110, '2nd';
         '01/18/2014 14:00:00', 120, '3rd'
         """      

下面的正規表達式描述了上述字元串對象提供的日期-時間資訊格式[4]:

In [91]: dt = re.compile("'[0-9/:\s]+'") # datetime      

使用上述正規表達式,我們可以查找所有日期-時間元素。一般來說,對字元串對象應用正規表達式還能帶來典型解析任務性能的提升。

In [92]: result = dt.findall(series)
         result
Out[92]: ["'01/18/2014 13:00:00'", "'01/18/2014 13:30:00'", "'01/18/2014
         14:00:00'"]      

正規表達式

解析字元串對象時,若考慮使用正規表達式,可以為相關操作帶來便利和高性能。

然後,可以對結果字元串對象進行解析,生成Python的日期時間(datetime)對象(用Python處理日期和時間資料的概述參見附錄A)。要解析包含日期時間資訊的字元串對象,我們必須提供解析方法的資訊——同樣是一個字元串對象:

In [93]: from datetime import datetime
         pydt = datetime.strptime(result[0].replace("'", ""),
                                  '%m/%d/%Y %H:%M:%S')
         pydt
Out[93]: datetime.datetime(2014, 1, 18, 13, 0)

In [94]: print(pydt)
         2014-01-18 13:00:00

In [95]: print(type(pydt))
         <class 'datetime.datetime'>      

後續内容會提供關于日期—時間資料、這些資料的處理以及datetime對象及其方法的更多資訊。現在我們隻是預覽一下金融中的這個重要主題。

3.2 基本資料結構

資料結構是包含其他對象(可能很多)的對象。Python提供了以下内建結構。

元組(tuple)

任意對象的集合;隻有少數可用方法。

清單(list)

任意對象的集合;有許多可用方法。

字典(dict)

鍵-值存儲對象。

集合(set)

其他獨特對象的無序集合對象。

3.2.1 元組

元組(tuple)是一種進階的資料結構,其應用相當簡單有限。它通過圓括号來提供對象定義:

In [96]: t = (1, 2.5, 'data')
         type(t)
Out[96]: tuple      

也可以去掉括号,提供以逗号分隔的多個對象:

In [97]: t = 1, 2.5, 'data'
         type(t)
Out[97]: tuple      

和Python中幾乎所有的資料結構相似,元組有内建的索引,利用該索引可以讀取元組的單個或者多個元素。重要的是記住Python使用零起點編号,元組的第3個元素在索引位置2上:

In [98]: t[2]
Out[98]: 'data'

In [99]: type(t[2])
Out[99]: str      

零起點編号

與MATLAB等其他程式設計語言不同,Python使用零起點編号方案。例如,元組對象的第一個元素索引值為0。

這種對象類型隻有兩個特殊方法:count()和index()。第一個方法計算某個對象的出現次數,第二個方法給出對象第一次出現位置的索引值:

In [100]: t.count('data')
Out[100]: 1

In [101]: t.index(1)
Out[101]: 0      

元組對象是不可變對象,這意味着一旦定義,它們就不容易更改。

3.2.2 清單

與元組對象相比,清單(list)類型的對象更靈活、更強大。從金融角度看,許多工作隻能用清單對象完成,例如存儲股票報價和附加新資料。清單對象通過方括号定義,其基本功能和行為與元組類似:

In [102]: l = [1, 2.5, 'data']
          l[2]
Out[102]: 'data'      

清單對象也可以使用list()函數定義或者轉換。下面的代碼通過轉換前一個例子中的元組對象來生成新的清單對象:

In [103]: l = list(t)
          l
Out[103]: [1, 2.5, 'data']

In [104]: type(l)
Out[104]: list      

除了元組對象的特性之外,清單對象還可以通過不同的方法來擴充和縮小。換句話說,字元串和元組對象是不可變序列對象(具有索引),一經建立不能更改,而清單對象是可變的,可以通過不同操作更改。您可以在現有清單對象中附加一個或者多個清單對象:

In [105]: l.append([4, 3]) ❶
          l
Out[105]: [1, 2.5, 'data', [4, 3]]

In [106]: l.extend([1.0, 1.5, 2.0]) ❷
          l
Out[106]: [1, 2.5, 'data', [4, 3], 1.0, 1.5, 2.0]

In [107]: l.insert(1, 'insert') ❸
          l
Out[107]: [1, 'insert', 2.5, 'data', [4, 3], 1.0, 1.5, 2.0]
In [108]: l.remove('data') ❹
          l
Out[108]: [1, 'insert', 2.5, [4, 3], 1.0, 1.5, 2.0]

In [109]: p = l.pop(3) ❺
          print(l, p)
          [1, 'insert', 2.5, 1.0, 1.5, 2.0] [4, 3]      

❶ 在尾部附加清單對象。

❷ 附加清單對象元素。

❸ 在索引位置之前插入對象。

❹ 删除第一次出現的對象。

❺ 删除并傳回索引位置的對象。

切片操作也很容易實作。這裡的切片(slicing)指的是将資料集分解為(感興趣的)較小部分:

In [110]: l[2:5] ❶
Out[110]: [2.5, 1.0, 1.5]      

❶ 傳回的是第3~5個元素。

表3-2提供了清單對象精選操作和方法的簡單說明。

Python提供的一些相當實用而靈活的通用資料結構

3.2.3 題外話:控制結構

控制結構(如for循環)本身就是一個主題,但是在Python中,最好在清單對象基礎上了解它。這是因為:循環一般來說都在清單對象上進行,這與其他語言中的常用标準有很大不同。看下面的例子,for循環在清單對象l索引值為2~4的元素上進行,功能是列印各個元素的平方。注意第二行中縮進(空白)的重要性:

In [111]: for element in l[2:5]:
              print(element ** 2)
          6.25
          1.0
          2.25      

與典型的基于計數器的循環相比,上述循環提供了很高的靈活性。基于計數器的循環也是Python的一個可選項,但是在(标準)清單對象range的基礎上完成的:

In [112]: r = range(0, 8, 1) ❶
          r
Out[112]: range(0, 8)

In [113]: type(r)
Out[113]: range      

❶ 參數依次是起始值、結束值和步長。

為了比較,下面我們使用range實作同一個循環:

In [114]: for i in range(2, 5):
              print(l[i] ** 2)
          6.25
          1.0
          2.25      

在清單上循環

在Python中,你可以在任意清單對象上循環,而不用管這些對象的内容是什麼,這往往可以避免引入計數器。

Python還提供了典型(條件)控制元素if、elif和else。它們的用途與其他語言的相同:

In [115]: for i in range(1, 10):
              if i % 2 == 0: ❶
                  print("%d is even" % i)
              elif i % 3 == 0:
                  print("%d is multiple of 3" % i)
              else:
                  print("%d is odd" % i)
          1 is odd
          2 is even
          3 is multiple of 3
          4 is even
          5 is odd
          6 is even
          7 is odd
          8 is even
          9 is multiple of 3
          % stands for modulo.      

❶ %代表取模運算。

同樣,while提供了另一種流程控制手段:

In [116]: total = 0
          while total < 100:
              total += 1
          print(total)
          100      

Python的特殊性之一是所謂的清單推導(List Comprehension)。這種方法不在現有清單對象上循環,而是以緊湊的方式通過循環生成清單對象:

In [117]: m = [i ** 2 for i in range(5)]
          m
Out[117]: [0, 1, 4, 9, 16]      

在某種意義上,它已經提供了一種方法,以較為隐含(而非顯式)的循環生成某種向量化代碼段(代碼向量化将在第4章和第5章中詳細讨論)。

3.2.4 題外話:函數式程式設計

Python也提供一些用于函數式程式設計支援的工具——在一整組輸入(在我們的例子中是清單對象)上應用某個函數。這些工具是過濾(filter)、映射(map)和歸納(reduce)。但是,我們首先需要一個函數定義。從簡單的功能出發,考慮以下的函數f,它傳回輸入x的平方數:

In [118]: def f(x):
              return x ** 2
          f(2)
Out[118]: 4      

當然,函數可能很複雜,它可能有多個輸入(參數對象)甚至多個輸出(傳回對象)。考慮以下函數:

In [119]: def even(x):
              return x % 2 == 0
          even(3)
Out[119]: False      

傳回對象是一個布爾值。這樣的函數可以用map()應用到整個清單對象:

In [120]: list(map(even, range(10)))
Out[120]: [True, False, True, False, True, False, True, False, True, False]      

為此,我們還可以使用lambda或者匿名函數,直接提供一個函數定義作為map()的參數:

In [121]: list(map(lambda x: x ** 2, range(10)))
Out[121]: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]      

函數也可以用于過濾清單對象。在下面的例子中,過濾器傳回清單對象中比對某個布爾條件(由even函數定義)的元素:

In [122]: list(filter(even, range(15)))
Out[122]: [0, 2, 4, 6, 8, 10, 12, 14]      

清單推導、函數式程式設計和匿名函數

在Python級别上盡可能避免循環被視為“好的習慣”。清單推導和函數式程式設計工具(如map、filter和reduce)為編寫緊湊(一般來說也更易于了解)無循環代碼提供了很大幫助。lambda或者匿名函數也是這方面的強大工具。

3.2.5 字典

字典(dict)對象就是可以按照鍵碼(例如,可能是字元串對象)讀取的資料字典,也是一種可變序列,是所謂的鍵—值存儲。清單對象是有序且可排序的,而字典對象通常是無序、不可排序的[5]。示例最能夠說明字典和清單對象的不同之處。字典對象定義用花括号實作:

In [123]: d = {
               'Name' : 'Angela Merkel',
               'Country' : 'Germany',
               'Profession' : 'Chancelor',
               'Age' : 64
               }
          type(d)
Out[123]: dict

In [124]: print(d['Name'], d['Age'])
          Angela Merkel 64      

同樣,該類對象也有一些内建方法:

In [125]: d.keys()
Out[125]: dict_keys(['Name', 'Country', 'Profession', 'Age'])

In [126]: d.values()
Out[126]: dict_values(['Angela Merkel', 'Germany', 'Chancelor', 64])

In [127]: d.items()
Out[127]: dict_items([('Name', 'Angela Merkel'), ('Country', 'Germany'),
          ('Profession', 'Chancelor'), ('Age', 64)])

In [128]: birthday = True
          if birthday:a
              d['Age'] += 1
          print(d['Age'])
          65      

從字典對象中獲得疊代器(Iterator)對象有多種方法。這種對象在循環時的表現與清單對象的表現類似:

In [129]: for item in d.items():
              print(item)
          ('Name', 'Angela Merkel')
          ('Country', 'Germany')
          ('Profession', 'Chancelor')
          ('Age', 65)

In [130]: for value in d.values():
              print(type(value))
          <class 'str'>
          <class 'str'>
          <class 'str'>
          <class 'int'>