Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
| Download

📚 The CoCalc Library - books, templates and other resources

Views: 96168
License: OTHER
1
"""This module contains a code example related to
2
3
Think Python, 2nd Edition
4
by Allen Downey
5
http://thinkpython2.com
6
7
Copyright 2015 Allen Downey
8
9
License: http://creativecommons.org/licenses/by/4.0/
10
"""
11
12
from __future__ import print_function, division
13
14
15
class LinearMap:
16
"""A simple implementation of a map using a list of tuples
17
where each tuple is a key-value pair."""
18
19
def __init__(self):
20
self.items = []
21
22
def add(self, k, v):
23
"""Adds a new item that maps from key (k) to value (v).
24
Assumes that they keys are unique."""
25
self.items.append((k, v))
26
27
def get(self, k):
28
"""Looks up the key (k) and returns the corresponding value,
29
or raises KeyError if the key is not found."""
30
for key, val in self.items:
31
if key == k:
32
return val
33
raise KeyError
34
35
36
class BetterMap:
37
"""A faster implementation of a map using a list of LinearMaps
38
and the built-in function hash() to determine which LinearMap
39
to put each key into."""
40
41
def __init__(self, n=100):
42
"""Appends (n) LinearMaps onto (self)."""
43
self.maps = []
44
for i in range(n):
45
self.maps.append(LinearMap())
46
47
def find_map(self, k):
48
"""Finds the right LinearMap for key (k)."""
49
index = hash(k) % len(self.maps)
50
return self.maps[index]
51
52
def add(self, k, v):
53
"""Adds a new item to the appropriate LinearMap for key (k)."""
54
m = self.find_map(k)
55
m.add(k, v)
56
57
def get(self, k):
58
"""Finds the right LinearMap for key (k) and looks up (k) in it."""
59
m = self.find_map(k)
60
return m.get(k)
61
62
63
class HashMap:
64
"""An implementation of a hashtable using a BetterMap
65
that grows so that the number of items never exceeds the number
66
of LinearMaps.
67
68
The amortized cost of add should be O(1) provided that the
69
implementation of sum in resize is linear."""
70
71
def __init__(self):
72
"""Starts with 2 LinearMaps and 0 items."""
73
self.maps = BetterMap(2)
74
self.num = 0
75
76
def get(self, k):
77
"""Looks up the key (k) and returns the corresponding value,
78
or raises KeyError if the key is not found."""
79
return self.maps.get(k)
80
81
def add(self, k, v):
82
"""Resize the map if necessary and adds the new item."""
83
if self.num == len(self.maps.maps):
84
self.resize()
85
86
self.maps.add(k, v)
87
self.num += 1
88
89
def resize(self):
90
"""Makes a new map, twice as big, and rehashes the items."""
91
new_map = BetterMap(self.num * 2)
92
93
for m in self.maps.maps:
94
for k, v in m.items:
95
new_map.add(k, v)
96
97
self.maps = new_map
98
99
100
def main():
101
import string
102
103
m = HashMap()
104
s = string.ascii_lowercase
105
106
for k, v in enumerate(s):
107
m.add(k, v)
108
109
for k in range(len(s)):
110
print(k, m.get(k))
111
112
113
if __name__ == '__main__':
114
main()
115
116