1、字典的實現python
dic 能夠使用list來實現
算法
i(索引) = hash(key) % solt(槽位數)bash
此時i重複了怎麼辦(hash衝突)?app
一、拉鍊法ide
每一個槽位上拉一個List,就是拉鍊法學習
In [6]: solts = [] # 初始化一個list In [7]: solts_num = 32 # 假設32個槽位 In [8]: for _ in range(solts_num): ...: solts.append([]) ...: In [9]: solts # 每一個槽位上都是一個list Out[9]: [[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []] ## 定義dict的put方法 In [10]: def put(solts, key, value): ...: i = hash(key) % solts_num ...: solts[i].append((key, value)) ...: ## 定義dict的get方法 In [12]: def get(solts, key): ...: i = hash(key) % solts_num ...: for k, v in solts[i]: ...: if k == key: ...: return v ...: raise KeyError(key) ...: ## 測試 In [23]: put(solts, 'a', 1) In [24]: solts Out[24]: [[('a', 1)], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []] In [25]: put(solts, 'b', 2) In [26]: put(solts, 'f', 9) In [27]: solts Out[27]: [[('a', 1)], [], [], [], [], [], [], [], [], [], [], [], [('f', 9)], [], [('b', 2)], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []] In [28]: get(solts, 'b') Out[28]: 2 In [29]: get(solts, 'f') Out[29]: 9 In [107]: get(solts, 'x') --------------------------------------------------------------------------- KeyError Traceback (most recent call last) <ipython-input-107-bdc41302b4b3> in <module>() ----> 1 get(solts, 'x') <ipython-input-100-31c1edecb2ae> in get(solts, key) 4 if k == key: 5 return v ----> 6 raise KeyError(key) 7 KeyError: 'x'
此時put一個已存在的key時:
測試
In [33]: put(solts, 'a', 11) In [34]: solts Out[34]: [[('a', 1), ('a', 11)], [], [], [], [], [], [], [], [], [], [], [], [('f', 9)], [], [('b', 2)], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []] In [35]: get(solts, 'a') Out[35]: 1
從新定put方法:
spa
In [87]: def put(solts, key, value): ...: i = hash(key) % solts_num ...: for p, (k, v) in enumerate(solts[i]): ...: if k == key: ...: solts[i][p] = (key, value) ...: else: ...: solts[i].append((key, value)) In [89]: solts Out[89]: [] In [90]: for _ in range(solts_num): ...: solts.append([]) ...: In [92]: put(solts, 'a', 1) In [94]: put(solts, 'b', 2) In [95]: put(solts, 'f', 8) In [96]: solts Out[96]: [[('a', 1)], [], [], [], [], [], [], [], [], [], [], [], [('f', 8)], [], [('b', 2)], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []] In [101]: get(solts, 'b') Out[101]: 2 In [102]: get(solts, 'f') Out[102]: 8 In [103]: get(solts, 'a') Out[103]: 11 In [104]: put(solts, 'b', 22) In [105]: get(solts, 'b') Out[105]: 22 In [106]: solts Out[106]: [[('a', 11), ('a', 11)], [], [], [], [], [], [], [], [], [], [], [], [('f', 8)], [], [('b', 22), ('b', 22)], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []] In [107]: get(solts, 'x') --------------------------------------------------------------------------- KeyError Traceback (most recent call last) <ipython-input-107-bdc41302b4b3> in <module>() ----> 1 get(solts, 'x') <ipython-input-100-31c1edecb2ae> in get(solts, key) 4 if k == key: 5 return v ----> 6 raise KeyError(key) 7 KeyError: 'x'
set在底層的實現就是一個忽略了value的dict
索引
二、開地址法ip
使用某個算法從新計算i,就交開地址法
經常使用,效率更高,
i = fn(key, i)
待後續學習