【Python】十二、字典的實現


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)


待後續學習

相關文章
相關標籤/搜索