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

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

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