2 class SortedDict(dict):
4 A dictionary that keeps its keys in the order in which they're inserted.
6 def __init__(self, data=None):
9 super(SortedDict, self).__init__(data)
10 if isinstance(data, dict):
11 self.keyOrder = data.keys()
14 for key, value in data:
15 if key not in self.keyOrder:
16 self.keyOrder.append(key)
18 def __deepcopy__(self, memo):
19 from copy import deepcopy
20 return self.__class__([(key, deepcopy(value, memo))
21 for key, value in self.iteritems()])
23 def __setitem__(self, key, value):
24 super(SortedDict, self).__setitem__(key, value)
25 if key not in self.keyOrder:
26 self.keyOrder.append(key)
28 def __delitem__(self, key):
29 super(SortedDict, self).__delitem__(key)
30 self.keyOrder.remove(key)
33 for k in self.keyOrder:
36 def pop(self, k, *args):
37 result = super(SortedDict, self).pop(k, *args)
39 self.keyOrder.remove(k)
41 # Key wasn't in the dictionary in the first place. No problem.
46 result = super(SortedDict, self).popitem()
47 self.keyOrder.remove(result[0])
51 return zip(self.keyOrder, self.values())
54 for key in self.keyOrder:
55 yield key, super(SortedDict, self).__getitem__(key)
58 return self.keyOrder[:]
61 return iter(self.keyOrder)
64 return [super(SortedDict, self).__getitem__(k) for k in self.keyOrder]
67 for key in self.keyOrder:
68 yield super(SortedDict, self).__getitem__(key)
70 def update(self, dict_):
71 for k, v in dict_.items():
72 self.__setitem__(k, v)
74 def setdefault(self, key, default):
75 if key not in self.keyOrder:
76 self.keyOrder.append(key)
77 return super(SortedDict, self).setdefault(key, default)
79 def value_for_index(self, index):
80 """Returns the value of the item at the given zero-based index."""
81 return self[self.keyOrder[index]]
83 def insert(self, index, key, value):
84 """Inserts the key, value pair before the item with the given index."""
85 if key in self.keyOrder:
86 n = self.keyOrder.index(key)
90 self.keyOrder.insert(index, key)
91 super(SortedDict, self).__setitem__(key, value)
94 """Returns a copy of this object."""
95 # This way of initializing the copy means it works for subclasses, too.
96 obj = self.__class__(self)
97 obj.keyOrder = self.keyOrder[:]
102 Replaces the normal dict.__repr__ with a version that returns the keys
103 in their sorted order.
105 return '{%s}' % ', '.join(['%r: %r' % (k, v) for k, v in self.items()])
108 super(SortedDict, self).clear()