目錄 | 上一節 (1.7 函數) | 下一節 (2.2 容器)python
本節以元組和字典爲表明介紹數據結構。git
Python 有一些原始數據類型:github
email_address = None
None
經常使用做可選值或缺失值的佔位符。它在條件語句中計算爲 False
。數據庫
if email_address: send_email(email_address, msg)
實際的程序具備更復雜的數據。例如,關於股票的持有信息:編程
100 shares of GOOG at $490.10
這是一個包含三個部分的「對象」:segmentfault
元組是分組在一塊兒的值的集合。數組
示例:數據結構
s = ('GOOG', 100, 490.1)
有時候會在語法上省略 ()
。編程語言
s = 'GOOG', 100, 490.1
特殊狀況(0 元組,1 元組)。函數
t = () # An empty tuple w = ('GOOG', ) # A 1-item tuple
元組通常用來表示簡單的記錄或結構。
一般,它是由多個部分組成的單個對象。這有一個很好的類比:元組就像數據庫表中的一行。
元組的內容是有序的(相似於數組)。
s = ('GOOG', 100, 490.1) name = s[0] # 'GOOG' shares = s[1] # 100 price = s[2] # 490.1
可是,元組的內容沒法修改。
>>> s[1] = 75 TypeError: object does not support item assignment
你能夠基於當前元組建立一個新元組。
s = (s[0], 75, s[2])
元組更多的是把相關的項打包到一個實體(entity)中。
s = ('GOOG', 100, 490.1)
而後,該元組很容易做爲單個對象傳遞給程序的其它部分。
要在其它地方使用元組,能夠把元組的各部分拆包爲變量。
name, shares, price = s print('Cost', shares * price)
左側變量的數目必須與元組的結構匹配。
name, shares = s # ERROR Traceback (most recent call last): ... ValueError: too many values to unpack
元組看起來像只讀列表。可是,元組最經常使用於由多個部分組成的單項。列表一般是類型相同的項的集合,
record = ('GOOG', 100, 490.1) # A tuple representing a record in a portfolio symbols = [ 'GOOG', 'AAPL', 'IBM' ] # A List representing three stock symbols
字典是鍵到值的映射。有時,字典也稱爲哈希表(hash table)或關聯數組(associative array)。鍵用做訪問值的索引。
s = { 'name': 'GOOG', 'shares': 100, 'price': 490.1 }
要從字典中獲取值,請使用鍵名。
>>> print(s['name'], s['shares']) GOOG 100 >>> s['price'] 490.10 >>>
要添加或修改值,請使用鍵名進行分配。
>>> s['shares'] = 75 >>> s['date'] = '6/6/2007' >>>
要刪除值,請使用 del
語句。
>>> del s['date'] >>>
當存在不少不一樣的值而且可能會修改或操做這些值時,字典頗有用。字典使代碼更具可讀性。
s['price'] # vs s[2]
在上次的幾個練習中,編寫了一個取數據文件 Data/portfolio.csv
的程序 。使用 csv
模塊,能夠輕鬆地逐行讀取文件。
>>> import csv >>> f = open('Data/portfolio.csv') >>> rows = csv.reader(f) >>> next(rows) ['name', 'shares', 'price'] >>> row = next(rows) >>> row ['AA', '100', '32.20'] >>>
儘管讀取文件很容易,可是與讀取數據相比,一般使用數據作更多的事情。例如,也許想存儲它並對其執行一些計算。不幸的是,原始的數據「行」並不能這樣作。例如,即便是簡單的數學計算也不行。
>>> row = ['AA', '100', '32.20'] >>> cost = row[1] * row[2] Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: can't multiply sequence by non-int of type 'str' >>>
要執行更多的操做,一般須要以某種方式解釋原始數據,並將其轉換爲更有用的對象類型,以便之後處理。有兩種簡單的方式能夠選擇:元組或者字典。
在交互式提示符下,建立如下表明上一行的元組,但數字列要轉換爲恰當的數字。
>>> t = (row[0], int(row[1]), float(row[2])) >>> t ('AA', 100, 32.2) >>>
使用這種方式,如今可使用股份數目乘以價格來計算總價,
>>> cost = t[1] * t[2] >>> cost 3220.0000000000005 >>>
在 Python 中,數學沒用了嗎?結果爲何是 3220.0000000000005?
這是計算機上浮點硬件的產物,只能在二進制(而不是十進制)中準確表示小數。即便是涉及十進制小數的簡單計算,也會引入小的偏差。這很正常,若是你以前沒有見過,可能會有點驚訝。
雖然在全部使用浮點小數的編程語言中都會發生這種狀況,可是打印的時候能夠把它隱藏,例如:
>>> print(f'{cost:0.2f}') 3220.00 >>>
元組是隻讀的。能夠經過嘗試把股份數目改成 75 來驗證這點。
>>> t[1] = 75 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment >>>
儘管沒法更改元組的內容,可是始終能夠建立一個全新的元組來替換舊的元組。
>>> t = (t[0], 75, t[2]) >>> t ('AA', 75, 32.2) >>>
每當像這樣從新分配現有變量名時,舊值就會被丟棄。雖然上面的賦值可能看起來像在修改元組,但其實是在建立一個新的元組,而且將舊的元組丟棄。
元組一般用於將值打包或拆包到變量中。請嘗試如下操做:
>>> name, shares, price = t >>> name 'AA' >>> shares 75 >>> price 32.2 >>>
取上面的變量並將其打包回元組中:
>>> t = (name, 2*shares, price) >>> t ('AA', 150, 32.2) >>>
能夠建立字典來替代元組。
>>> d = { 'name' : row[0], 'shares' : int(row[1]), 'price' : float(row[2]) } >>> d {'name': 'AA', 'shares': 100, 'price': 32.2 } >>>
計算持有的總價:
>>> cost = d['shares'] * d['price'] >>> cost 3220.0000000000005 >>>
將此示例與上面涉及元組的相同的計算進行比較,將股份數目修改成 75。
>>> d['shares'] = 75 >>> d {'name': 'AA', 'shares': 75, 'price': 32.2 } >>>
與元組不一樣,字典能夠自由修改。添加一些屬性:
>>> d['date'] = (6, 11, 2007) >>> d['account'] = 12345 >>> d {'name': 'AA', 'shares': 75, 'price':32.2, 'date': (6, 11, 2007), 'account': 12345} >>>
若是將一個字典轉換爲列表,則將得到其全部的鍵:
>>> list(d) ['name', 'shares', 'price', 'date', 'account'] >>>
相似地,若是使用 for
語句對字典進行迭代,則將得到其全部的鍵。
>>> for k in d: print('k =', k) k = name k = shares k = price k = date k = account >>>
嘗試使用這個同時執行查找的變體:
>>> for k in d: print(k, '=', d[k]) name = AA shares = 75 price = 32.2 date = (6, 11, 2007) account = 12345 >>>
也可使用 keys()
方法得到全部的鍵:
>>> keys = d.keys() >>> keys dict_keys(['name', 'shares', 'price', 'date', 'account']) >>>
在這裏,keys()
稍微有點不一樣,它返回的是一個 dict_keys
對象。
這是對原始字典的覆蓋,它始終提供當前字典的鍵——即便字典改變了。例如,試試一下操做:
>>> del d['account'] >>> keys dict_keys(['name', 'shares', 'price', 'date']) >>>
請注意,儘管沒有再次調用 d.keys()
,但鍵'account'
消失了。
一個更優雅地一塊兒使用鍵和值的方式是使用 items()
方法。這能夠得到鍵值組成的元組 (key, value)
。
>>> items = d.items() >>> items dict_items([('name', 'AA'), ('shares', 75), ('price', 32.2), ('date', (6, 11, 2007))]) >>> for k, v in d.items(): print(k, '=', v) name = AA shares = 75 price = 32.2 date = (6, 11, 2007) >>>
若是有相似於 items
的元組,那麼可使用 dict()
函數建立一個字典。請嘗試如下操做:
>>> items dict_items([('name', 'AA'), ('shares', 75), ('price', 32.2), ('date', (6, 11, 2007))]) >>> d = dict(items) >>> d {'name': 'AA', 'shares': 75, 'price':32.2, 'date': (6, 11, 2007)} >>>