一、字典的实现

dic 可以使用list来实现

i(索引) = hash(key) % solt(槽位数)

此时i重复了怎么办(hash冲突)?


1、拉链法

 每个槽位上拉一个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)
 in ()
----> 1 get(solts, 'x')

 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方法:

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)
 in ()
----> 1 get(solts, 'x')

 in get(solts, key)
      4         if k == key:
      5             return v
----> 6     raise KeyError(key)
      7 

KeyError: 'x'

    set在底层的实现就是一个忽略了value的dict


2、开地址法

  使用某个算法重新计算i,就交开地址法

  常用,效率更高,

i = fn(key, i)


待后续学习