@@ -77,154 +77,32 @@ class _Link(object):
77
77
78
78
class OrderedDict (dict ):
79
79
'Dictionary that remembers insertion order'
80
- # An inherited dict maps keys to values.
81
- # The inherited dict provides __getitem__, __len__, __contains__, and get.
82
- # The remaining methods are order-aware.
83
- # Big-O running times for all methods are the same as regular dictionaries.
84
-
85
- # The internal self.__map dict maps keys to links in a doubly linked list.
86
- # The circular doubly linked list starts and ends with a sentinel element.
87
- # The sentinel element never gets deleted (this simplifies the algorithm).
88
- # The sentinel is in self.__hardroot with a weakref proxy in self.__root.
89
- # The prev links are weakref proxies (to prevent circular references).
90
- # Individual links are kept alive by the hard reference in self.__map.
91
- # Those hard references disappear when a key is deleted from an OrderedDict.
92
-
93
- def __init__ (self , other = (), / , ** kwds ):
94
- '''Initialize an ordered dictionary. The signature is the same as
95
- regular dictionaries. Keyword argument order is preserved.
96
- '''
97
- try :
98
- self .__root
99
- except AttributeError :
100
- self .__hardroot = _Link ()
101
- self .__root = root = _proxy (self .__hardroot )
102
- root .prev = root .next = root
103
- self .__map = {}
104
- self .__update (other , ** kwds )
105
-
106
- def __setitem__ (self , key , value ,
107
- dict_setitem = dict .__setitem__ , proxy = _proxy , Link = _Link ):
108
- 'od.__setitem__(i, y) <==> od[i]=y'
109
- # Setting a new item creates a new link at the end of the linked list,
110
- # and the inherited dictionary is updated with the new key/value pair.
111
- if key not in self :
112
- self .__map [key ] = link = Link ()
113
- root = self .__root
114
- last = root .prev
115
- link .prev , link .next , link .key = last , root , key
116
- last .next = link
117
- root .prev = proxy (link )
118
- dict_setitem (self , key , value )
119
-
120
- def __delitem__ (self , key , dict_delitem = dict .__delitem__ ):
121
- 'od.__delitem__(y) <==> del od[y]'
122
- # Deleting an existing item uses self.__map to find the link which gets
123
- # removed by updating the links in the predecessor and successor nodes.
124
- dict_delitem (self , key )
125
- link = self .__map .pop (key )
126
- link_prev = link .prev
127
- link_next = link .next
128
- link_prev .next = link_next
129
- link_next .prev = link_prev
130
- link .prev = None
131
- link .next = None
132
-
133
- def __iter__ (self ):
134
- 'od.__iter__() <==> iter(od)'
135
- # Traverse the linked list in order.
136
- root = self .__root
137
- curr = root .next
138
- while curr is not root :
139
- yield curr .key
140
- curr = curr .next
141
-
142
- def __reversed__ (self ):
143
- 'od.__reversed__() <==> reversed(od)'
144
- # Traverse the linked list in reverse order.
145
- root = self .__root
146
- curr = root .prev
147
- while curr is not root :
148
- yield curr .key
149
- curr = curr .prev
150
-
151
- def clear (self ):
152
- 'od.clear() -> None. Remove all items from od.'
153
- root = self .__root
154
- root .prev = root .next = root
155
- self .__map .clear ()
156
- dict .clear (self )
157
80
158
81
def popitem (self , last = True ):
159
82
'''Remove and return a (key, value) pair from the dictionary.
160
83
161
84
Pairs are returned in LIFO order if last is true or FIFO order if false.
162
85
'''
86
+ if last :
87
+ return super ().popitem ()
163
88
if not self :
164
89
raise KeyError ('dictionary is empty' )
165
- root = self .__root
166
- if last :
167
- link = root .prev
168
- link_prev = link .prev
169
- link_prev .next = root
170
- root .prev = link_prev
171
- else :
172
- link = root .next
173
- link_next = link .next
174
- root .next = link_next
175
- link_next .prev = root
176
- key = link .key
177
- del self .__map [key ]
178
- value = dict .pop (self , key )
179
- return key , value
90
+ key = next (iter (self .keys ()))
91
+ return (key , self .pop (key ))
180
92
181
93
def move_to_end (self , key , last = True ):
182
94
'''Move an existing element to the end (or beginning if last is false).
183
95
184
96
Raise KeyError if the element does not exist.
185
97
'''
186
- link = self .__map [key ]
187
- link_prev = link .prev
188
- link_next = link .next
189
- soft_link = link_next .prev
190
- link_prev .next = link_next
191
- link_next .prev = link_prev
192
- root = self .__root
98
+ value = self .pop (key )
193
99
if last :
194
- last = root .prev
195
- link .prev = last
196
- link .next = root
197
- root .prev = soft_link
198
- last .next = link
100
+ super ().__setitem__ (key , value )
199
101
else :
200
- first = root .next
201
- link .prev = root
202
- link .next = first
203
- first .prev = soft_link
204
- root .next = link
205
-
206
- def __sizeof__ (self ):
207
- sizeof = _sys .getsizeof
208
- n = len (self ) + 1 # number of links including root
209
- size = sizeof (self .__dict__ ) # instance dictionary
210
- size += sizeof (self .__map ) * 2 # internal dict and inherited dict
211
- size += sizeof (self .__hardroot ) * n # link objects
212
- size += sizeof (self .__root ) * n # proxy objects
213
- return size
214
-
215
- update = __update = _collections_abc .MutableMapping .update
216
-
217
- def keys (self ):
218
- "D.keys() -> a set-like object providing a view on D's keys"
219
- return _OrderedDictKeysView (self )
220
-
221
- def items (self ):
222
- "D.items() -> a set-like object providing a view on D's items"
223
- return _OrderedDictItemsView (self )
224
-
225
- def values (self ):
226
- "D.values() -> an object providing a view on D's values"
227
- return _OrderedDictValuesView (self )
102
+ tmp = self .copy ()
103
+ self .clear ()
104
+ super ().__setitem__ (key , value )
105
+ self .update (tmp )
228
106
229
107
__ne__ = _collections_abc .MutableMapping .__ne__
230
108
@@ -236,31 +114,17 @@ def pop(self, key, default=__marker):
236
114
is raised.
237
115
238
116
'''
239
- marker = self .__marker
240
- result = dict .pop (self , key , marker )
241
- if result is not marker :
242
- # The same as in __delitem__().
243
- link = self .__map .pop (key )
244
- link_prev = link .prev
245
- link_next = link .next
246
- link_prev .next = link_next
247
- link_next .prev = link_prev
248
- link .prev = None
249
- link .next = None
250
- return result
251
- if default is marker :
252
- raise KeyError (key )
253
- return default
117
+ if default is self .__marker :
118
+ return super ().pop (key )
119
+ else :
120
+ return super ().pop (key , default )
254
121
255
122
def setdefault (self , key , default = None ):
256
123
'''Insert key with a value of default if key is not in the dictionary.
257
124
258
125
Return the value for key if key is in the dictionary, else default.
259
126
'''
260
- if key in self :
261
- return self [key ]
262
- self [key ] = default
263
- return default
127
+ return super ().setdefault (key , default )
264
128
265
129
@_recursive_repr ()
266
130
def __repr__ (self ):
0 commit comments