11class Array (object ):
2- def __init__ (self , size = 30 , init = None ):
2+ def __init__ (self , size = 32 , init = None ):
33 self .size = size
4- self .items = [init ]* size
4+ self .items = [init ] * size
5+ def clear (self , value = None ):
6+ for i in range (len (self )):
7+ self .items [i ] = value
8+ def __len__ (self ):
9+ return self .size
510 def __getitem__ (self , index ):
611 return self .items [index ]
712 def __setitem__ (self , index , value ):
813 self .items [index ] = value
9- def __len__ (self ):
10- return self .size
11- def clear (self ):
12- for i in range (len (self .size )):
13- self .items [i ] = init
1414 def __iter__ (self ):
15- for i in self .items :
16- yield i
15+ for item in self .items :
16+ yield item
1717class Slot (object ):
18- def __init__ (self , value = None , key = None ):
18+ def __init__ (self , key = None , value = None ):
1919 self .key , self .value = key , value
2020class HashTable (object ):
21- EMPTY = None
2221 UNUSED = None
22+ EMPTY = Slot ()
2323 def __init__ (self ):
24- self ._table = Array (20 , HashTable .UNUSED )
24+ self ._table = Array (8 , init = HashTable .UNUSED )
2525 self .length = 0
26- @property
27- def _load_factor (self ):
28- return self .length / len (self ._table )
2926 def __len__ (self ):
3027 return self .length
3128 def _hash (self , key ):
32- return abs (hash (key )% len (self ._table ))
33- def _find_key (self , key ):
29+ return abs (hash (key )) % len (self ._table )
30+ @property
31+ def load_factor (self ):
32+ return self .length / len (self ._table )
33+ def find_key (self , key ):
3434 index = self ._hash (key )
35- _len = self .length
3635 while self ._table [index ] is not HashTable .UNUSED :
37- if self ._table [index ] is HashTable .EMPTY :
38- index = (index * 5 + 1 ) % _len
39- continue
40- elif self ._table [index ].key == key :
36+ if self ._table [index ] is not HashTable .EMPTY and self ._table [index ].key == key :
4137 return index
42- else :
43- index = (index * 5 + 1 ) / _len
38+ index = (index * 5 + 1 )% len (self ._table )
4439 return None
45- def _slot_can_insert (self , index ):
46- return (self ._table [index ] is HashTable .EMPTY or HashTable .UNUSED )
47- def _find_slots_for_insert (self , key ):
40+ def find_key_to_insert (self , key ):
4841 index = self ._hash (key )
49- _len = self .length
50- while not _slot_can_insert (index ):
51- index = (index * 5 + 1 )% _len
42+ while self ._table [index ] not in (HashTable .UNUSED , HashTable .EMPTY ):
43+ index = (index * 5 + 1 ) % len (self ._table )
5244 return index
53- def __contains__ (self , key ):
54- index = _find_key (key )
55- return index is not None
5645 def add (self , key , value ):
57- if key in self :
58- index = self ._find_key (key )
46+ if self .find_key (key ):
5947 self ._table [index ].value = value
60- return False
6148 else :
62- index = _find_slots_for_insert (key )
63- self . _table [ index ] = Slot (value , key )
64- self .length += 1
65- if self ._load_factor () >= 0.8 :
66- self . _rehash ()
67- return True
68- def rehash (self ):
49+ index = self . find_key_to_insert (key )
50+ slot = Slot (key , value )
51+ self ._table [ index ] = slot
52+ self .length += 1
53+ if self . load_factor >= 0.8 :
54+ self . _rehash_table ()
55+ def _rehash_table (self ):
6956 old_table = self ._table
70- newsize = len (self ) * 2
57+ newsize = len (self . _table ) * 2
7158 self ._table = Array (newsize , HashTable .UNUSED )
72- self .length = 0
73- for slot in old_table :
74- if slot is not HashTable .UNUSED and slot is not HashTable .EMPTY :
75- index = self ._find_slots_for_insert (slot .key )
76- self ._table [index ] = slot
77- self .length += 1
78- def get (self , key , default = None ):
79- index = self ._find_key (key )
80- if index is None :
81- return default
82- else :
83- return self ._table [index ].value
59+ for i in old_table :
60+ if i not in (HashTable .UNUSED , HashTable .EMPTY ):
61+ index = self .find_key_to_insert (i .key )
62+ self ._table [index ] = i
8463 def remove (self , key ):
85- index = self ._find_key (key )
86- if index is None :
87- raise KeyError ()
88- value = self ._table [index ].value
89- self ._table [index ].key = HashTable .EMPTY
90- self .length -= 1
91- return value
64+ index = self .find_key (key )
65+ if index is not None :
66+ self ._table [index ] = HashTable .EMPTY
67+ self .length -= 1
68+ else :
69+ raise KeyError ('Not Found' )
9270 def __iter__ (self ):
93- for slot in self ._table :
94- if slot not in (HashTable .EMPTY , HashTable .UNUSED ):
95- yield slot .key
71+ for item in self ._table :
72+ if item not in (HashTable .UNUSED , HashTable .EMPTY ):
73+ yield (item .key , item .value )
74+ def __contains__ (self , key ):
75+ if self .find_key (key ):
76+ return True
77+ return False
78+ def get (self , key , default = None ):
79+ index = self .find_key (key )
80+ if index is not None :
81+ return self ._table [index ].value
82+ return default
0 commit comments