1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
# -*- coding: utf-8 -*-
class odict(dict):
"""This one uses generators in places where it can, and plays nicely
with deepcopy."""
def __init__(self, d={}):
self._keys = d.keys()
dict.__init__(self, d)
def __delitem__(self, key):
dict.__delitem__(self, key)
self._keys.remove(key)
def __setitem__(self, key, item):
dict.__setitem__(self, key, item)
# a peculiar sharp edge from copy.deepcopy
# we'll have our set item called without __init__
if not hasattr(self, '_keys'):
self._keys = [key,]
if key not in self._keys:
self._keys.append(key)
def clear(self):
dict.clear(self)
self._keys = []
def items(self):
for i in self._keys:
yield i, self[i]
def keys(self):
return self._keys
def popitem(self):
if len(self._keys) == 0:
raise KeyError('dictionary is empty')
else:
key = self._keys[-1]
val = self[key]
del self[key]
return key, val
def setdefault(self, key, failobj = None):
dict.setdefault(self, key, failobj)
if key not in self._keys:
self._keys.append(key)
def update(self, d):
for key in d.keys():
if not self.has_key(key):
self._keys.append(key)
dict.update(self, d)
def values(self):
for i in self._keys:
yield self[i]
def move(self, key, index):
""" Move the specified to key to *before* the specified index. """
try:
cur = self._keys.index(key)
except ValueError:
raise KeyError(key)
self._keys.insert(index, key)
# this may have shifted the position of cur, if it is after index
if cur >= index: cur = cur + 1
del self._keys[cur]
def index(self, key):
if not self.has_key(key):
raise KeyError(key)
return self._keys.index(key)
if __name__ == '__main__':
od = odict()
|