前言:
我一直覺得對我來說學習知識很忌諱不系統。本篇內容與上一篇 自定義序列類是有聯系的。
上一篇比較通范的了解了序列類的一些協議和特性,并且有些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元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

