前言:
我一直覺得對我來說學習知識很忌諱不系統。本篇內容與上一篇 自定義序列類是有聯系的。
上一篇比較通范的了解了序列類的一些協議和特性,并且有些list的內容。這篇更加具體到set和dict這兩個序列類。
以此來了解python序列類的具體應用。(這篇比較簡單)(感覺具體比抽象都更容易理解,但是也要學會思考把具體對象抽象化來表達,即提取共性)
content:
1.dict在abc中的序列類型和繼承關系
2.dict實現了的常用方法
3.我可不可以繼承dict這種序列類?
4.set和frozenset
5.set和dict的原理
==============
?
1.dict在abc中的序列類型和繼承關系
dict在collection.abc中,實際上是屬于MutableMapping(可變mapping)類型。
跟上篇對可變序列類繼承的分析一樣,MutableMapping繼承了Mapping的一些功能并且加了一些可變的特性,
Mapping繼承了Collection。接下來的繼承和上篇的一樣。
?
2.dict實現了的常用方法
如果用的是pycharm,還是用ctrl+b就能跳到python對dict的定義。
常用:
a = { " 1 " :{ " a " : " aa " }, " 2 " :{ " b " : " bb " }} # 清空字典 a.clear() # 淺拷貝字典 淺拷貝雖然可以正常賦值,但是如果 my_dopy_dict 中的值進行了改變,則 a 中的值也會進行對應的改變 my_dopy_dict = a.copy() # 深拷貝 深拷貝則是實實在在的在內存當中聲明了一個新的變量 import copy new_dict = copy.deepcopy(a) # get函數 dict.get(要查找的key,如果沒找到對應key的內容返回的數據) print (a.get( " 3 " ,{1: " 3 " })) # {1: '3'} # dict.fromkeys() 函數用于創建一個新字典,以序列 seq 中元素做字典的鍵 seq可以是可迭代的,value 為字典所有鍵對應的初始值。 my_list = [1, 2, 3 ] my_new_dict = dict.fromkeys(my_list, { " 222 " : " 3434 " }) # {1: {'222': '3434'}, 2: {'222': '3434'}, 3: {'222': '3434'}} # setdefault() 函數和 get()方法 類似, # 如果鍵不存在于字典中,將會添加鍵并將值設為默認值。 # 如果存在,則將會返回該key對應的value a.setdefault( " 3 " , " cc " ) # a= {'1': {'a': 'aa'}, '2': {'b': 'bb'}, '3': 'cc'} print (a.setdefault( " 2 " , " cc " )) # 返回{'b': 'bb'} # update() 函數把字典dict2的鍵/值對更新到dict里。 # 如果字典b中有與a相同的key,則會把a中的key對應的value進行更新 # 如果字典b中有a中沒有的key,則a會將未有的key與value添加進去 b = { " 3 " : " cc " , " 2 " : " dd " } a.update(b) print (a) # {'1': {'a': 'aa'}, '2': 'dd', '3': 'cc'}
?
3.我可不可以繼承dict這種序列類?(dict的子類)
a.如果我偷懶想實現dict這種類型,能不能直接繼承這種序列類呢?同理list是否可以?
例:繼承dict,并且重寫設置dict key的value時調用的魔法函數,使其值變為2倍
class Mydict(dict): def __setitem__ (self, key, value): super(). __setitem__ (key, value*2 ) a =Mydict(b=1 ) print (a) a[ ' b ' ]=1 print (a)
輸出:
可以發現,原來同樣功能和效果的,我們重寫方法后,第一種方法去設置key的value值這一操作并沒有調用我們重寫的方法。
所以并不建議去繼承python的這種序列類。
?
b.有沒有什么辦法我實在想繼承?
python里專門給了個UserDict類,可以實現想要的繼承Dict類的效果
from collections import UserDict class Mydict(UserDict): def __setitem__ (self, key, value): super(). __setitem__ (key, value*2 ) mydict = Mydict(one = 1) # {'one': 2} 調用__setitem__這個魔法函數 mydict[ " one " ] = 2 # {'one': 4} 這種方式也可以調用__setitem__
輸出:
?
?c.python中Dcit實際也有子類實現:defaultdict
使用:
from collections import defaultdict # 這個是dict的子類 mydict = defaultdict(dict) myvalue = mydict[ " bai " ] # 如果不存在的話,返回{}
輸出:
?
4.set和frozenset
a.兩者是啥有啥特點?
set:集合(無序,不重復,可變)
frozenset:不可變集合(無序,不重復,不可變)
a=set( ' abcdee ' ) a.add( ' f ' ) print (a) another_set =set( ' defgh ' ) # 添加數據 # a.update(another_set) # print(a) # 集合的差集 re_set= a.difference(another_set) # 減法實現于__ior__魔法函數 re_set2=a- another_set # 集合的交集& re_set3=a& another_set # 集合的并集| re_set4=a| another_set print (re_set) print (re_set2) print (re_set3) print (re_set4) # 也可以用if in判斷(實現于__contains__魔法函數) if ' a ' in re_set: print ( ' I am a set ' )
?
5.set和dict的原理
之前就提過,set的性能棒的。dict的查詢性能遠比起list要好。
并且list中隨著list數據的增大,查找時間會增大,而dict不會。
這是為什么呢?
因為dict使用hash這種數據結構存儲。set也是。
a.dict的散列表
特點:

先計算a的散列值,查找表源是否為空,
因為a是不變的,所以如果表源為空,那么就會拋出key error。
如果表源不為空,也有可能是其他key,查看key是否是要查找的key。
如果是其他key,重新散列循環查找。
?
c.這種hash結構在ptthon中的特點
-?我們可以用__hash__這個魔法函數實現可hash對象
?- dict內存開銷比較大,這是hash表的特點。
- 實際上python內部類和對象,都是dict。
- dict存儲順序和元素添加順序有關。
- 插入數據后檢查剩余空間引發的重hash,會影響原來的數據(比如地址)。
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
