輕鬆初探 Python 篇(五)— dict 和 set 知識彙總

這是「AI 學習之路」的第 5 篇,「Python 學習」的第 5 篇python

小之的公衆號 : WeaponZhi算法

介紹一下 dict 和 set 這兩個數據結構。數據結構

dict

dict 是 Python 內置的字典類型,熟悉 Java 的同窗能夠把它類比爲 Map。dict 使用鍵值對來存儲(key-value),它的查找速度特別快。函數

dict 通常用在什麼場景呢?假設咱們須要根據公司名字查找公司地址,按照咱們以前的寫法,咱們須要先創建兩個 list ,一個存儲公司名字,一個存儲公司總部地址,而後查找公司名字,記錄好列表位置,再從地址列表查找到具體元素,你還得保證兩個表元素位置必須一一對應。不只如此,若是表很長,那遍歷查找效率將會很是低。學習

>>> Inc = ['騰訊','阿里','百度']
>>> adress = ['深圳','杭州','北京']
>>> BaiduAdress = adress[Inc.index('百度')]
>>> BaiduAdress
'北京'
複製代碼

咱們如今用 dict 實現,使用一個「公司-地址」這樣的鍵值對來進行存儲數據,查找的時候,咱們只須要輸入公司名字,就能夠查找到對應的地址,同時,不論 dict 的數據有多少,查找單項的速度都是同樣的,並且很是迅速。spa

>>> Inc_dict = {'騰訊':'深圳','阿里':'杭州','百度':'北京'}
>>> Inc_dict['百度']
'北京'
複製代碼

dict 速度這麼快的原理就是使用了空間換取時間的方法,將無限集映射到一個有限集中。經過一個散列函數來計算每個 key 應該存放在內存中的位置,而後把 value 存儲在內存的這個位置上,等到須要取出 key 對應的 value 的時候,只須要經過函數計算出這個位置,而後直接去拿就好了。是否是有點像咱們查字典的步驟呢?設計

經過散列函數求出的最終值就是對應的哈希值(Hash),Java 中的 Map 最經常使用的實現 HashMap 也是用相似的原理來設計的。Hash 算法也是數據結構中特別重要的一個知識點,因此若是咱們計算機的基本功紮實,學哪門語言的時候都是融會貫通的3d

固然,散列函數自己比較複雜,還要牽扯到衝突的解決問題,簡單來講,不一樣的 key 經過散列函數求得的內存位置多是同樣的,這樣就致使了衝突,解決這種衝突的方法有不少,Python 設計者選擇了開放定址法,在衝突的時候用另外一個不一樣的函數再計算。在這裏我就不深刻討論了,有興趣的同窗能夠查閱下相關資料。code

咱們有不少種方式進行 dict 的初始化,下面幾種初始化方式都會得到{"one": 1, "two": 2, "three": 3}:cdn

>>> a = dict(one=1,two=2,three=3)
>>> b = {'one':1,'two':2,'three':3}
>>> c = dict(zip(['one','two','three'],[1,2,3]))
>>> d = dict([('two',2),('one',1),('three',3)])
>>> e = dict({'three':3,'one':1,'two':2})
>>> a == b == c == d == e
True
複製代碼

除了經過初始化之外,還能夠經過 key 來放入值,再次傳入相同 key ,不一樣 value,將會覆蓋前面傳入的 value。若是某個 key 不存在,獲取該 key 的 value 將會報 KeyError 錯誤。

>>> Inc_dict['途牛'] = '南京'
>>> Inc_dict['途牛']
'南京'
>>> Inc_dict['途牛'] = '金陵'
>>> Inc_dict['途牛']
'金陵'
>>> Inc_dict['小米']
KeyError:'小米'
複製代碼

爲了防止獲取 key 不存在的狀況。咱們能夠用 in 來判斷 dict 中是否已經存儲過以這個 key 來存儲的鍵值對。或者用 get() 方法來獲取 value,若是 key 不存在,get() 將返回 None,能夠設置一個參數來表示 key 不存在時候的默認返回值。

>>> '小米' in Inc_dict
False
>>> Inc_dict.get('小米')
>>> Inc_dict.get('小米','北京')
北京
複製代碼

經過 pop(key) 方法,來返回並刪除對應的 value:

>>> Inc_dict.pop('騰訊')
'深圳'
>>> Inc_dict
{'阿里':'杭州','百度':'北京','途牛':'金陵'}
複製代碼

最後介紹下 dict 的迭代,咱們知道 list 迭代能夠簡單的經過 for 來遍歷,dict 迭代須要多作一些操做。

>>> d = {'a':1,'b':2,'c':3}
>>> for key in d:
...     print(key)
...
'a'
'c'
'b'
複製代碼

dict 默認的迭代方式是迭代 key ,若是你須要迭代 value 能夠經過 d.values() 來獲取 value 的列表

>>> for value in d.values()
...     print(value)
...
1
3
2
複製代碼

固然,你還能夠同時迭代 key 和 value

>>> for k, v in d.items():
...     print(k, v)
...
a 1
c 3
b 2
複製代碼

細心的同窗必定發現了迭代的順序和咱們初始化定義的順序是不一樣的,以前也提到了,dict 內部存放順序是根據散列函數決定的,因此最後的存放順序不必定和插入順序一致,那咱們迭代順序顯然是不肯定的了。

dict 的設計是典型的以空間換取時間,你們學習 Python 越深刻就會發現 Python 的設計裏有不少這樣的設計, Python 設計的時候,大概已經不是內存最大就 4,500K 的年代了吧(手動嬉笑)。因此 dict 的特色就是,查找和插入的速度很是快,而且不隨元素數量的增加而變慢。

注意:key 必須是不可變對象(字符串,整數等),若是 key 是 list,就會報錯 TypeError: unhashable type: 'list',tuple 雖然是不可變對象,但若是傳入的 tuple 元素有可變對象,依然會報錯。

>>> d = {'a':1}
>>> d = {'a':1,(1,):2}
>>> d = {'a':1,(1,):2,(1,[1]):3}
TypeError: unhashable type: 'list'
複製代碼

set

set 和 dict 很像,不過 set 不存儲鍵值對,你能夠把它想像成只存儲 key 的 dict,也能夠理解成數學中的無序無重複集合這個概念。因此在 set 中是沒有重複元素的,也只能存放不可變元素。咱們能夠經過一個 list 來建立 set。一樣,也是用大括號表示。

>>> s = set([1,2,3])
>>> s
{1,2,3}
>>> s = set([1,2,3,3,3])
>>> s
{1,2,3}
複製代碼

咱們能夠看到,重複的元素自動被過濾了,同時 set 也是無序的,雖然建立時候顯示看起來好像是有序的。咱們來看看 set 的一些經常使用方法。

>>> s.add(4)
>>> s
{1,2,3,4}
>>> s.add(4)
>>> s
{1,2,3,4}
複製代碼

add(key)添加元素到 set 中,但添加劇復元素將不會生效

>>> s.remove(4)
>>> s
{1,2,3}
>>> s.remove(4)
KeyError: 4
>>> s1 = {1,2,3}
>>> s2 = {2,3,4}
>>> s1 & s2
{2,3}
>>> s1 | s2
{1,2,3,4}
複製代碼

remove(key)刪除元素,若是 key 不存在會報錯。同時,set 以前說過能夠當作是集合,因此能夠作一些交併集的操做。


歡迎關注個人公衆號

相關文章
相關標籤/搜索