1. 程式人生 > 實用技巧 >Python中常用型別的基本操作(字典,列表,元祖等)[持續更新]

Python中常用型別的基本操作(字典,列表,元祖等)[持續更新]

字典dict常用操作

字典也是Python提供的一種常用的資料結構,它用於存放具有對映關係的資料。
比如有份成績表資料,語文:79,數學:80,英語:92,這組資料看上去像兩個列表,但這兩個列表的元素之間有一定的關聯關係。如果單純使用兩個列表來儲存這組資料,則無法記錄兩組資料之間的關聯關係。
為了儲存具有對映關係的資料,Python 提供了字典,字典相當於儲存了兩組資料,其中一組資料是關鍵資料,被稱為 key;另一組資料可通過 key 來訪問,被稱為 value。形象地看,字典中 key 和 value 的關聯關係如圖 1 所示:



圖 1 字典儲存的關聯資料

由於字典中的 key 是非常關鍵的資料,而且程式需要通過 key 來訪問 value,因此字典中的 key 不允許重複。

程式既可使用花括號語法來建立字典,也可使用 dict() 函式來建立字典。實際上,dict 是一種型別,它就是 Python 中的字典型別。
在使用花括號語法建立字典時,花括號中應包含多個 key-value 對,key 與 value 之間用英文冒號隔開;多個 key-value 對之間用英文逗號隔開。
如下程式碼示範了使用花括號語法建立字典:

scores = {'語文': 89, '數學': 92, '英語': 93}
print(scores)
# 空的花括號代表空的dict
empty_dict = {}
print(empty_dict)
# 使用元組作為dict的key
dict2 = {(20, 30):'
good', 30:'bad'} print(dict2)

上面程式中第 1 行程式碼建立了一個簡單的 dict,該 dict 的 key 是字串,value 是整數;第 4 行程式碼使用花括號建立了一個空的字典;第 7 行程式碼建立的字典中第一個 key 是元組,第二個 key 是整數值,這都是合法的。

需要指出的是,元組可以作為 dict 的 key,但列表不能作為元組的 key。這是由於 dict 要求 key 必須是不可變型別,但列表是可變型別,因此列表不能作為元組的 key。

在使用 dict() 函式建立字典時,可以傳入多個列表或元組引數作為 key-value 對,每個列表或元組將被當成一個 key-value 對,因此這些列表或元組都只能包含兩個元素。例如如下程式碼:

vegetables = [('celery', 1.58), ('brocoli', 1.29), ('lettuce', 2.19)]
# 建立包含3組key-value對的字典
dict3 = dict(vegetables)
print(dict3) # {'celery': 1.58, 'brocoli': 1.29, 'lettuce': 2.19}
cars = [['BMW', 8.5], ['BENS', 8.3], ['AUDI', 7.9]]
# 建立包含3組key-value對的字典
dict4 = dict(cars)
print(dict4) # {'BMW': 8.5, 'BENS': 8.3, 'AUDI': 7.9} 

如果不為 dict() 函式傳入任何引數,則代表建立一個空的字典。例如如下程式碼:

# 建立空的字典
dict5 = dict()
print(dict5) # {}

還可通過為 dict 指定關鍵字引數建立字典,此時字典的 key 不允許使用表示式。例如如下程式碼:

# 使用關鍵字引數來建立字典
dict6 = dict(spinach = 1.39, cabbage = 2.59)
print(dict6) # {'spinach': 1.39, 'cabbage': 2.59}

上面粗體字程式碼在建立字典時,其 key 直接寫 spinach、cabbage,不需要將它們放在引號中。

字典的基本用法

對於初學者而言,應牢記字典包含多個 key-value 對,而 key 是字典的關鍵資料,因此程式對字典的操作都是基於 key 的。基本操作如下:

通過 key 訪問 value 。
通過 key 新增 key-value 對。
通過 key 刪除 key-value 對。
通過 key 修改 key-value 對。
通過 key 判斷指定 key-value 對是否存在。
通過 key 訪問 value 使用的也是方括號語法,就像前面介紹的列表和元組一樣,只是此時在方括號中放的是 key,而不是列表或元組中的索引。

如下程式碼示範了通過 key 訪問 value:

scores = {'語文': 89}
# 通過key訪問value
print(scores['語文'])

如果要為 dict 新增 key-value 對,只需為不存在的 key 賦值即可:

# 對不存在的key賦值,就是增加key-value對
scores['數學'] = 93
scores[92] = 5.7
print(scores) # {'語文': 89, '數學': 93, 92: 5.7} 

如果要刪除宇典中的 key-value 對,則可使用 del 語句。例如如下程式碼:

# 使用del語句刪除key-value對
del scores['語文']
del scores['數學']
print(scores) # {92: 5.7} 

如果對 dict 中存在的 key-value 對賦值,新賦的 value 就會覆蓋原有的 value,這樣即可改變 dict 中的 key-value 對。例如如下程式碼:

cars = {'BMW': 8.5, 'BENS': 8.3, 'AUDI': 7.9}
# 對存在的key-value對賦值,改變key-value對
cars['BENS'] = 4.3
cars['AUDI'] = 3.8
print(cars) # {'BMW': 8.5, 'BENS': 4.3, 'AUDI': 3.8} 

如果要判斷字典是否包含指定的 key,則可以使用 in 或 not in 運算子。需要指出的是,對於 dict 而言,in 或 not in 運算子都是基於 key 來判斷的。例如如下程式碼:

# 判斷cars是否包含名為'AUDI'的key
print('AUDI' in cars) # True
# 判斷cars是否包含名為'PORSCHE'的key
print('PORSCHE' in cars) # False
print('LAMBORGHINI' not in cars) # True

通過上面介紹可以看出,字典的 key 是它的關鍵。換個角度來看,字典的 key 就相當於它的索引,只不過這些索引不一定是整數型別,字典的 key 可以是任意不可變型別。
可以這樣說,字典相當於索引是任意不可變型別的列表:而列表則相當於 key 只能是整數的字典。因此,如果程式中要使用的字典的 key 都是整數型別,則可考慮能否換成列表。
此外,還有一點需要指出,列表的索引總是從 0 開始、連續增大的;但字典的索引即使是整數型別,也不需要從 0 開始,而且不需要連續。因此,列表不允許對不存在的索引賦值:但字典則允許直接對不存在的 key 賦值,這樣就會為字典增加一個 key-value 對。

列表不允許對不存在的索引賦值,但字典則允許直接對不存在的 key 賦值。

字典的常用方法

字典由 dict 類代表,因此我們同樣可使用 dir(dict) 來檢視該類包含哪些方法。在互動式直譯器中輸入 dir(dict) 命令,將看到如下輸出結果:

>>> dir(dict)
['clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']
>>>

下面介紹 dict 的一些方法。

clear()方法

clear() 用於清空字典中所有的 key-value 對,對一個字典執行 clear() 方法之後,該字典就會變成一個空字典。例如如下程式碼:

cars = {'BMW': 8.5, 'BENS': 8.3, 'AUDI': 7.9}
print(cars) # {'BMW': 8.5, 'BENS': 8.3, 'AUDI': 7.9}
# 清空cars所有key-value對
cars.clear()
print(cars) # {}

get()方法

get() 方法其實就是根據 key 來獲取 value,它相當於方括號語法的增強版,當使用方括號語法訪問並不存在的 key 時,字典會引發 KeyError 錯誤;但如果使用 get() 方法訪問不存在的 key,該方法會簡單地返回 None,不會導致錯誤。例如如下程式碼:

cars = {'BMW': 8.5, 'BENS': 8.3, 'AUDI': 7.9}
# 獲取'BMW'對應的value
print(cars.get('BMW')) # 8.5
print(cars.get('PORSCHE')) # None
print(cars['PORSCHE']) # KeyError

update()方法

update() 方法可使用一個字典所包含的 key-value 對來更新己有的字典。在執行 update() 方法時,如果被更新的字典中己包含對應的 key-value 對,那麼原 value 會被覆蓋;如果被更新的字典中不包含對應的 key-value 對,則該 key-value 對被新增進去。例如如下程式碼:

cars = {'BMW': 8.5, 'BENS': 8.3, 'AUDI': 7.9}
cars.update({'BMW':4.5, 'PORSCHE': 9.3})
print(cars) 

從上面的執行過程可以看出,由於被更新的 dict 中己包含 key 為“AUDI”的 key-value 對,因此更新時該 key-value 對的 value 將被改寫;但如果被更新的 dict 中不包含 key 為“PORSCHE”的 key-value 對,那麼更新時就會為原字典增加一個 key-value 對。

items()、keys()、values()

items()、keys()、values() 分別用於獲取字典中的所有 key-value 對、所有 key、所有 value。這三個方法依次返回 dict_items、dict_keys 和 dict_values 物件,Python 不希望使用者直接操作這幾個方法,但可通過 list() 函式把它們轉換成列表。如下程式碼示範了這三個方法的用法:

cars = {'BMW': 8.5, 'BENS': 8.3, 'AUDI': 7.9}
# 獲取字典所有的key-value對,返回一個dict_items物件
ims = cars.items()
print(type(ims)) # <class 'dict_items'>
# 將dict_items轉換成列表
print(list(ims)) # [('BMW', 8.5), ('BENS', 8.3), ('AUDI', 7.9)]
# 訪問第2個key-value對
print(list(ims)[1]) # ('BENS', 8.3)
# 獲取字典所有的key,返回一個dict_keys物件
kys = cars.keys()
print(type(kys)) # <class 'dict_keys'>
# 將dict_keys轉換成列表
print(list(kys)) # ['BMW', 'BENS', 'AUDI']
# 訪問第2個key
print(list(kys)[1]) # 'BENS'
# 獲取字典所有的value,返回一個dict_values物件
vals = cars.values()
# 將dict_values轉換成列表
print(type(vals)) # [8.5, 8.3, 7.9]
# 訪問第2個value
print(list(vals)[1]) # 8.3

從上面程式碼可以看出,程式呼叫字典的 items()、keys()、values() 方法之後,都需要呼叫 list() 函式將它們轉換為列表,這樣即可把這三個方法的返回值轉換為列表。

在 Python 2.x 中,items()、keys()、values() 方法的返回值本來就是列表,完全可以不用 list() 函式進行處理。當然,使用 list() 函式處理也行,列表被處理之後依然是列表。

pop方法

pop() 方法用於獲取指定 key 對應的 value,並刪除這個 key-value 對。如下方法示範了 pop() 方法的用法:

cars = {'BMW': 8.5, 'BENS': 8.3, 'AUDI': 7.9}
print(cars.pop('AUDI')) # 7.9
print(cars) # {'BMW': 8.5, 'BENS': 8.3} 

此程式中,第 2 行程式碼將會獲取“AUDI”對應的 value,並刪除該 key-value 對。

popitem()方法

popitem() 方法用於隨機彈出字典中的一個 key-value 對。

此處的隨機其實是假的,正如列表的 pop() 方法總是彈出列表中最後一個元素,實際上字典的 popitem() 其實也是彈出字典中最後一個 key-value 對。由於字典儲存 key-value 對的順序是不可知的,因此開發者感覺字典的 popitem() 方法是“隨機”彈出的,但實際上字典的 popitem() 方法總是彈出底層儲存的最後一個 key-value 對。

如下程式碼示範了 popitem() 方法的用法:

cars = {'AUDI': 7.9, 'BENS': 8.3, 'BMW': 8.5}
print(cars)
# 彈出字典底層儲存的最後一個key-value對
print(cars.popitem()) # ('AUDI', 7.9)
print(cars) # {'BMW': 8.5, 'BENS': 8.3}

由於實際上 popitem 彈出的就是一個元組,因此程式完全可以通過序列解包的方式用兩個變數分別接收 key 和 value。例如如下程式碼:

# 將彈出項的key賦值給k、value賦值給v
k, v = cars.popitem()
print(k, v) # BENS 8.3

setdefault()方法

setdefault() 方法也用於根據 key 來獲取對應 value 的值。但該方法有一個額外的功能,即當程式要獲取的 key 在字典中不存在時,該方法會先為這個不存在的 key 設定一個預設的 value,然後再返回該 key 對應的 value。

總之,setdefault() 方法總能返回指定 key 對應的 value;如果該 key-value 對存在,則直接返回該 key 對應的 value;如果該 key-value 對不存在,則先為該 key 設定預設的 value,然後再返回該 key 對應的 value。

如下程式碼示範了 setdefault() 方法的用法:

cars = {'BMW': 8.5, 'BENS': 8.3, 'AUDI': 7.9}
# 設定預設值,該key在dict中不存在,新增key-value對
print(cars.setdefault('PORSCHE', 9.2)) # 9.2
print(cars)
# 設定預設值,該key在dict中存在,不會修改dict內容
print(cars.setdefault('BMW', 3.4)) # 8.5
print(cars) 

fromkeys()方法

fromkeys() 方法使用給定的多個 key 建立字典,這些 key 對應的 value 預設都是 None;也可以額外傳入一個引數作為預設的 value。該方法一般不會使用字典物件呼叫(沒什麼意義),通常會使用 dict 類直接呼叫。例如如下程式碼:

# 使用列表建立包含2個key的字典
a_dict = dict.fromkeys(['a', 'b'])
print(a_dict) # {'a': None, 'b': None}
# 使用元組建立包含2個key的字典
b_dict = dict.fromkeys((13, 17))
print(b_dict) # {13: None, 17: None}
# 使用元組建立包含2個key的字典,指定預設的value
c_dict = dict.fromkeys((13, 17), 'good')
print(c_dict) # {13: 'good', 17: 'good'}

使用字典格式化字串

前面章節介紹過,在格式化字串時,如果要格式化的字串模板中包含多個變數,後面就需要按順序給出多個變數,這種方式對於字串模板中包含少量變數的情形是合適的,但如果字串模板中包含大量變數,這種按順序提供變數的方式則有些不合適。可改為在字串模板中按 key 指定變數,然後通過字典為字串模板中的 key 設定值。

例如如下程式:

# 字串模板中使用key
temp = '教程是:%(name)s, 價格是:%(price)010.2f, 出版社是:%(publish)s'
book = {'name':'Python基礎教程', 'price': 99, 'publish': 'C語言中文網'}
# 使用字典為字串模板中的key傳入值
print(temp % book)
book = {'name':'C語言小白變怪獸', 'price':159, 'publish': 'C語言中文網'}
# 使用字典為字串模板中的key傳入值
print(temp % book)

執行上面程式,可以看到如下輸出結果:

教程是:Python基礎教程, 價格是:0000099.00, 出版社是:C語言中文網
教程是:C語言小白變怪獸, 價格是:0000159.00, 出版社是:C語言中文網