1. 程式人生 > >python教程(七)·字典

python教程(七)·字典

字符 deepcopy 關鍵字 trace item 讀者 copy模塊 英語 知識

本文介紹本系列教程最後一個數據結構——字典


在現實生活中,查英語字典的時候,我們通常根據單詞來查找意思。而python中的字典也是類似的,根據特定的 “鍵”(單詞)來查找 “值”(意思)。

字典的基本使用

下面以電話簿為例,我們的電話簿記錄的是電話號碼。當要查找電話號碼時,我們根據人名來查找其電話號碼,所以人名就是字典的鍵,電話號碼就是字典的值。假設有下面這樣的人名和電話號碼的電話簿:

人名=>電話
Aganzo=>1230
Jack=>0221
Lee=>1354
Emilie=>2479

創建字典

現在我們來創建一個字典來表示這個電話簿:

>>> phonebook={'Aganzo':'1230', 'Jack':'0221', 'Lee':'1354', 'Emilie':'2479'}
>>> phonebook
{'Aganzo': '1230', 'Jack': '0221', 'Lee': '1354', 'Emilie': '2479'}
>>> 

從上面可以看出,創建字典的基本格式為{ 鍵1:值1, 鍵2:值2, 鍵3:值3 ...}。除了這種方法,我們還可以通過dict函數傳遞關鍵字參數來創建字典,像下面這樣:

>>> phonebook = dict(Aganzo='1230', Jack='0221', Lee='1354', Emilie='2479') # 關鍵字參數就是字典的鍵,參數值就是字典的值
>>> phonebook
{'Aganzo': '1230', 'Jack': '0221', 'Lee': '1354', 'Emilie': '2479'}
>>> 

我們常用第一種方式創建字典,第二種方式比較少用,而且第二種方式有一個缺點:因為關鍵字參數會變為字典的鍵,所以鍵必須符合參數的命名規則(字母或下劃線_開頭,其後是數字、字母或下劃線)。

補充:創建空字典有兩種方法,一種是直接使用{};另一種是調用dict函數時,參數留空,即dict();像鍵:值這樣的東西叫做字典的 “項”

字典基本操作

字典的基本操作有:

先來說“查”:我們可以通過名字來查找電話簿中的電話號碼,在字典中類似這樣,通過“鍵”來查“值”,基本格式為字典[鍵]

>>> phonebook['Aganzo']
'1230'
>>> phonebook['Jack']
'0221'
>>> phonebook['Lily']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'Lily'
>>> 

從上面的代碼可以看出,我們的“電話簿”中不存在Lily的電話號碼,可知,當字典中不存在要查的元素時,python會提示報錯。我們可以在查之前確認字典中是否有對應的項,使用成員運算符in

>>> 'Lily' in phonebook # 不存在
False
>>> 'Jack' in phonebook # 存在
True
>>> 

或者查看“電話簿”中所有人的電話號碼:

>>> for key in phonebook:
...     print('%s=>%s' % (key, phonebook[key]))
... 
Aganzo=>1230
Jack=>0221
Lee=>1354
Emilie=>2479
>>> 

再來說“改”:此時得知Lee更換了電話號碼為112233,需要對電話簿進行更改,使用如下代碼:

>>> phonebook['Lee'] = '112233'
>>> phonebook
{'Aganzo': '1230', 'Jack': '0221', 'Lee': '112233', 'Emilie': '2479'}
>>> 

再到“增”:假設新認識了一位朋友Zieg,得到了朋友的電話號碼為123456,需要在“電話簿”中新增一項,和“改”操作一樣,使用賦值運算符=

>>> phonebook['Zieg'] = '123456'
>>> phonebook
{'Aganzo': '1230', 'Jack': '0221', 'Lee': '112233', 'Emilie': '2479', 'Zieg': '123456'}
>>> 

最後說“刪”:朋友Jack與你絕交了(世事無常╮(╯▽╰)╭),你決定刪除他的聯系方式,此時你狠心地運行了下面的代碼:

>>> del phonebook['Jack']
>>> phonebook
{'Aganzo': '1230', 'Lee': '112233', 'Emilie': '2479', 'Zieg': '123456'}
>>> 

“電話簿”中再也沒有了Jack的電話號碼……

小結

好了,一個簡單的示例過後,相信大家能理解字典的使用方法了,讓我們來一個小小的總結:

創建字典的方法:

  • 通過花括號創建 x = {鍵1:值1, 鍵2:值2, 鍵3:值3 ...}
  • 通過dict函數創建 x = dict(key1=value1, key2=value2, key3=value3 ...)
  • 創建空字典可以使用 x = {}x = dict()

字典的基本操作:

  • 增:x[‘abc‘] = 123 (鍵‘abc‘不存在)
  • 刪:del x[‘abc‘]
  • 改:x[‘abc] += 1x[‘abc‘] = 2x[‘abc‘] *= 10……(鍵‘abc‘存在)
  • 查:result = x[‘abc‘]print(x[‘abc‘])……(鍵‘abc‘存在)

補充:字典的用法和列表類似,只不過列表索引元素的時候使用的是數字作鍵,而字典大多數時候使用字符串索引元素。


關於字典的鍵,還有一點是要說清楚的:前面我們使用字典的時候都是使用了字符串類型的鍵,可我沒有說字典的鍵只能是字符串!

實際上,字典的鍵可以是任意的不可變類型,如:字符串(最常用)、元組、浮點數、整數。


字典方法

字典也是對象,和列表一樣,字典也提供了一些實用的方法,下面是介紹

clear

clear方法用於清空字典中的所有項:

>>> d = {'name':'feather', 'age':18}
>>> d
{'name': 'feather', 'age': 18}
>>> d.clear()
>>> d
{}
>>> 

這個方法是原地的操作,意思就是操作對象是在字典本身,這和直接將變量賦值為空字典是不一樣的,從下面的例子可以看出:

>>> x = {'a':1}
>>> y = x # y變量引用的字典和x變量引用的是同一個字典
>>> x = {} # 將x變量引用改為另一個字典,這個字典是空字典
>>> x
{}
>>> y # y變量引用的字典沒有被改變
{'a': 1}
>>> 

copy

copy方法用於返回一個新字典,這個新字典和原來的字典擁有相同的項:

>>> x = {'name':'feather', 'blog':['https://blog.csdn.net/lonely_feather', 'https://featherl.gitee.io/']}
>>> y = x.copy()
>>> y['name'] = 'Lee'
>>> y['blog'].append('https://www.cnblogs.com/featherl/') 
>>> x
{'name': 'feather', 'blog': ['https://blog.csdn.net/lonely_feather', 'https://featherl.gitee.io/', 'https://www.cnblogs.com/featherl/']}
>>> y
{'name': 'Lee', 'blog': ['https://blog.csdn.net/lonely_feather', 'https://featherl.gitee.io/', 'https://www.cnblogs.com/featherl/']}
>>> 

可以看到,y字典是從x復制而來的,所以改變y字典的鍵為‘name‘的項的時候並不影響x字典,要註意的是,y[‘blog‘].append(‘https://www.cnblogs.com/featherl/‘)這句代碼不屬於修改y字典,這是修改y字典的鍵為‘blog‘的項引用的列表,而y字典和x字典的‘blog‘項引用的是同一個列表(因為y字典的項是從x字典中復制而來的),所以修改這個列表的時候,在x和y兩個字典上都可以看到效果。

這種問題是因為copy方法是“淺復制”,copy方法僅僅把相同的值存儲到了一個新的字典裏,要想避免這種問題,需要使用“深復制”,可以使用copy模塊的deepcopy函數來實現:

>>> from copy import deepcopy
>>> x = {'list':[1,2,3]}
>>> y = deepcopy(x)
>>> y['list'].append(4)
>>> x
{'list': [1, 2, 3]}
>>> y
{'list': [1, 2, 3, 4]}
>>> 

fromkeys

fromkeys方法用給定的鍵創建新字典,每個鍵對應的默認值都為None:

>>> {}.fromkeys(['name'])
{'name': None}
>>> dict.fromkeys(['name', 'age'])
{'name': None, 'age': None}

上面代碼的第一個例子中,我們創建了一個空字典,然後使用這個空字典的fromkeys方法創建了一個新字典,第二個例子中,我們直接使用dict這個類(實際上dict不是函數,是一個“類”)的fromkeys方法創建新字典。

我們還可以自己設置默認值:

>>> dict.fromkeys(['name', 'age'], '???')
{'name': '???', 'age': '???'}

get

get方法使用給定的鍵訪問字典中的項,不過,如果字典中不存在該項時,get方法返回默認值None,而不是報錯:

>>> x = {'name':'Lee'}
>>> x.get('age')
>>> print(x.get('name'))
Lee
>>> print(x.get('age'))
None

同樣的,這個默認值也是可以自己設定的:

>>> x = {'name':'Lee'}
>>> x.get('age', '???')
'???'

update

update方法將一個新字典合並到當前字典,當存在相同的鍵,用新字典的值進行覆蓋:

>>> x = {'name':'Lee'}
>>> x = {'name':'Lee', 'blog':'https://featherl.gitee.io'}
>>> y = {'name':'feather', 'age':18}
>>> x.update(y)
>>> x
{'name': 'feather', 'blog': 'https://featherl.gitee.io', 'age': 18}

pop

pop方法用來返回指定鍵的項,並將該項從字典中移除:

>>> x = {1:1, 2:2, 3:3}
>>> x.pop(1)
1
>>> x
{2: 2, 3: 3}

上面的例子同時也證明了字典的鍵不一定是字符串。

popitem

popitem方法隨機挑選一個項返回,並刪除這個項。字典不同於列表,字典的項是沒有順序,不同的機器或者不同版本的python,其字典存儲項的順序可能是不一樣的,故popitem方法具體處理哪一項是沒法預測的。

使用舉例如下:

>>> x = {1:1, 2:2, 3:3}
>>> x.pop
x.pop(      x.popitem(  
>>> help(x.popitem)

>>> x.popitem()
(3, 3)
>>> x.popitem()
(2, 2)
>>> x.popitem()
(1, 1)
>>> x.popitem()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'popitem(): dictionary is empty'

當字典為空的時候,該方法拋出錯誤。

items

items方法返回字典的所有的項,每個項為一個形式為(key, value)的元組,返回的類型是一種類似列表的類型,可以使用for循環叠代,但是沒有列表的方法,最好先使用list轉換成列表:

>>> x = {'name':'Lee', 'age':18}
>>> x.items()
dict_items([('name', 'Lee'), ('age', 18)])
>>> list(x.items())  # 轉換成列表
[('name', 'Lee'), ('age', 18)]

註意:在python2中此方法還有後面的keys、values方法返回的就是列表類型,不過我們學的是python3,要註意區分。

類似items的方法還有:

  • keys方法返回字典的所有的鍵(類似列表的類型)
  • values方法返回字典的所有的值(類似列表的類型)

到此為止,本系列教程的python數據結構已經介紹完了,在本系列教程只是介紹了python中如何使用常用數據結構,並沒有講實現原理。而數據結構在計算機領域是不可或缺的,希望對數據結構了解甚少的讀者可以認真學習一下數據結構的相關知識。

等學習完文件操作後,我們將用一個小項目實踐一下(其實忽略文件操作,目前學到的知識還是可以做很多東西的),敬請期待! ( ̄︶ ̄)↗

python教程(七)·字典