天天看點

風火程式設計--python的集合set和字典dict的特性如果不存在傳回預設值

《流暢的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)
           

繼續閱讀