《流暢的python》讀書筆記(二)
第3章 字典和集合
3.1 散列
可散列對象應實作了: hash()和__eq__()方法
原子類型的資料可散列,
不可變集合可散列,
元組隻有當所有元素可散列的時候才是可散列的
3.3 字典的操作
如果不存在傳回預設值
a = d.get("4", 4)
# 如果鍵不存在,添加并傳回預設值
b = d.setdefault("5", 1)
# 删除并傳回鍵對應的值,如果鍵不存在傳回預設值
c = d.pop("6", 3)
# 删除并傳回最後一個加入的鍵對應的鍵值對
e = d.popitem()
f = d.popitem()
print(d, a, b, c, e, f)
3.5映射鍊ChainMap
合并多個字典
from collections import ChainMap
d1 = {}.fromkeys("1239", 0)
dd = ChainMap(d1, d)
# 用法同字典,會從前開始查找鍵,找到為止.
print(dd.keys())
部分有序的字典
collections子產品下的OrderedDict可以取到首尾兩個元素
from collections import OrderedDict
od = OrderedDict.fromkeys(“123”, 1)
od[“4”] = 4
first = od.popitem(last=False)
last = od.popitem()
print(first, last)
3.7 不可變映射
from types import MappingProxyType
d = dict(one=1,two=2,three=3)
p = MappingProxyType(d)
print(p)
d["one"] = "one"
print(p)
# 對代理進行修改會報錯
p["one"] = 1
隻有set序列可以做減法, 但是set不能做加法
3.8 集合論
空集合用set()表示
# difference()求多個集合的補集
s = set("123456")
seq1 = "123"
seq2 = "0451"
# r = s-set(seq1)-set(seq2)
r = s.difference(seq1,seq2)
print(r)
# update()求多個集合的并集
r = s.update(seq1,seq2)
print(r, s) # 集合可變,沒有傳回值
3.9 底層知識
對set和dict.keys()進行in檢查時,元素的個數對運算效率幾乎沒有影響
set和dict.keys是散清單(稀疏 數組), 每個元素都是以表元的形式存儲, 每個表元包括建和值的引用.每個表元大小一緻, 可以通過偏移量來讀取.python會保證1/3的表元作為擴充空間, 達到門檻值後會将資料複制到更大的記憶體空間.
散清單查詢速度快,但是空間開銷巨大. 自定義的類中可以通過指定__slots__将執行個體屬性的存儲方式從字典改成元組.
dict.keys()是有順序的, 順序是key的添加順序, 但是不能通過索引取值, 可以先用list()轉成清單.
向字典中添加新元素的時候如果發生散列沖突, 則會改變原有鍵的順序, 是以不能在疊代中修改字典.應該先放入新的字典, 疊代結束後再更新. set()與dict,keys()相同
dict.items()/dict.keys()/dict.values()都是字典視圖,是動态同步的,但是不能主動修改.
3.10 建立字典視圖
from type import MappingProxyType
dv = MappingProxyType(dict)