Statistics
| Branch: | Revision:

root / scripts / ordereddict.py @ a22f123c

History | View | Annotate | Download (4 kB)

1 e89ac222 Michael Roth
# Copyright (c) 2009 Raymond Hettinger
2 e89ac222 Michael Roth
#
3 e89ac222 Michael Roth
# Permission is hereby granted, free of charge, to any person
4 e89ac222 Michael Roth
# obtaining a copy of this software and associated documentation files
5 e89ac222 Michael Roth
# (the "Software"), to deal in the Software without restriction,
6 e89ac222 Michael Roth
# including without limitation the rights to use, copy, modify, merge,
7 e89ac222 Michael Roth
# publish, distribute, sublicense, and/or sell copies of the Software,
8 e89ac222 Michael Roth
# and to permit persons to whom the Software is furnished to do so,
9 e89ac222 Michael Roth
# subject to the following conditions:
10 e89ac222 Michael Roth
#
11 e89ac222 Michael Roth
#     The above copyright notice and this permission notice shall be
12 e89ac222 Michael Roth
#     included in all copies or substantial portions of the Software.
13 e89ac222 Michael Roth
#
14 e89ac222 Michael Roth
#     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 e89ac222 Michael Roth
#     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
16 e89ac222 Michael Roth
#     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 e89ac222 Michael Roth
#     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18 e89ac222 Michael Roth
#     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19 e89ac222 Michael Roth
#     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 e89ac222 Michael Roth
#     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 e89ac222 Michael Roth
#     OTHER DEALINGS IN THE SOFTWARE.
22 e89ac222 Michael Roth
23 e89ac222 Michael Roth
from UserDict import DictMixin
24 e89ac222 Michael Roth
25 e89ac222 Michael Roth
class OrderedDict(dict, DictMixin):
26 e89ac222 Michael Roth
27 e89ac222 Michael Roth
    def __init__(self, *args, **kwds):
28 e89ac222 Michael Roth
        if len(args) > 1:
29 e89ac222 Michael Roth
            raise TypeError('expected at most 1 arguments, got %d' % len(args))
30 e89ac222 Michael Roth
        try:
31 e89ac222 Michael Roth
            self.__end
32 e89ac222 Michael Roth
        except AttributeError:
33 e89ac222 Michael Roth
            self.clear()
34 e89ac222 Michael Roth
        self.update(*args, **kwds)
35 e89ac222 Michael Roth
36 e89ac222 Michael Roth
    def clear(self):
37 e89ac222 Michael Roth
        self.__end = end = []
38 e89ac222 Michael Roth
        end += [None, end, end]         # sentinel node for doubly linked list
39 e89ac222 Michael Roth
        self.__map = {}                 # key --> [key, prev, next]
40 e89ac222 Michael Roth
        dict.clear(self)
41 e89ac222 Michael Roth
42 e89ac222 Michael Roth
    def __setitem__(self, key, value):
43 e89ac222 Michael Roth
        if key not in self:
44 e89ac222 Michael Roth
            end = self.__end
45 e89ac222 Michael Roth
            curr = end[1]
46 e89ac222 Michael Roth
            curr[2] = end[1] = self.__map[key] = [key, curr, end]
47 e89ac222 Michael Roth
        dict.__setitem__(self, key, value)
48 e89ac222 Michael Roth
49 e89ac222 Michael Roth
    def __delitem__(self, key):
50 e89ac222 Michael Roth
        dict.__delitem__(self, key)
51 e89ac222 Michael Roth
        key, prev, next = self.__map.pop(key)
52 e89ac222 Michael Roth
        prev[2] = next
53 e89ac222 Michael Roth
        next[1] = prev
54 e89ac222 Michael Roth
55 e89ac222 Michael Roth
    def __iter__(self):
56 e89ac222 Michael Roth
        end = self.__end
57 e89ac222 Michael Roth
        curr = end[2]
58 e89ac222 Michael Roth
        while curr is not end:
59 e89ac222 Michael Roth
            yield curr[0]
60 e89ac222 Michael Roth
            curr = curr[2]
61 e89ac222 Michael Roth
62 e89ac222 Michael Roth
    def __reversed__(self):
63 e89ac222 Michael Roth
        end = self.__end
64 e89ac222 Michael Roth
        curr = end[1]
65 e89ac222 Michael Roth
        while curr is not end:
66 e89ac222 Michael Roth
            yield curr[0]
67 e89ac222 Michael Roth
            curr = curr[1]
68 e89ac222 Michael Roth
69 e89ac222 Michael Roth
    def popitem(self, last=True):
70 e89ac222 Michael Roth
        if not self:
71 e89ac222 Michael Roth
            raise KeyError('dictionary is empty')
72 e89ac222 Michael Roth
        if last:
73 e89ac222 Michael Roth
            key = reversed(self).next()
74 e89ac222 Michael Roth
        else:
75 e89ac222 Michael Roth
            key = iter(self).next()
76 e89ac222 Michael Roth
        value = self.pop(key)
77 e89ac222 Michael Roth
        return key, value
78 e89ac222 Michael Roth
79 e89ac222 Michael Roth
    def __reduce__(self):
80 e89ac222 Michael Roth
        items = [[k, self[k]] for k in self]
81 e89ac222 Michael Roth
        tmp = self.__map, self.__end
82 e89ac222 Michael Roth
        del self.__map, self.__end
83 e89ac222 Michael Roth
        inst_dict = vars(self).copy()
84 e89ac222 Michael Roth
        self.__map, self.__end = tmp
85 e89ac222 Michael Roth
        if inst_dict:
86 e89ac222 Michael Roth
            return (self.__class__, (items,), inst_dict)
87 e89ac222 Michael Roth
        return self.__class__, (items,)
88 e89ac222 Michael Roth
89 e89ac222 Michael Roth
    def keys(self):
90 e89ac222 Michael Roth
        return list(self)
91 e89ac222 Michael Roth
92 e89ac222 Michael Roth
    setdefault = DictMixin.setdefault
93 e89ac222 Michael Roth
    update = DictMixin.update
94 e89ac222 Michael Roth
    pop = DictMixin.pop
95 e89ac222 Michael Roth
    values = DictMixin.values
96 e89ac222 Michael Roth
    items = DictMixin.items
97 e89ac222 Michael Roth
    iterkeys = DictMixin.iterkeys
98 e89ac222 Michael Roth
    itervalues = DictMixin.itervalues
99 e89ac222 Michael Roth
    iteritems = DictMixin.iteritems
100 e89ac222 Michael Roth
101 e89ac222 Michael Roth
    def __repr__(self):
102 e89ac222 Michael Roth
        if not self:
103 e89ac222 Michael Roth
            return '%s()' % (self.__class__.__name__,)
104 e89ac222 Michael Roth
        return '%s(%r)' % (self.__class__.__name__, self.items())
105 e89ac222 Michael Roth
106 e89ac222 Michael Roth
    def copy(self):
107 e89ac222 Michael Roth
        return self.__class__(self)
108 e89ac222 Michael Roth
109 e89ac222 Michael Roth
    @classmethod
110 e89ac222 Michael Roth
    def fromkeys(cls, iterable, value=None):
111 e89ac222 Michael Roth
        d = cls()
112 e89ac222 Michael Roth
        for key in iterable:
113 e89ac222 Michael Roth
            d[key] = value
114 e89ac222 Michael Roth
        return d
115 e89ac222 Michael Roth
116 e89ac222 Michael Roth
    def __eq__(self, other):
117 e89ac222 Michael Roth
        if isinstance(other, OrderedDict):
118 e89ac222 Michael Roth
            if len(self) != len(other):
119 e89ac222 Michael Roth
                return False
120 e89ac222 Michael Roth
            for p, q in  zip(self.items(), other.items()):
121 e89ac222 Michael Roth
                if p != q:
122 e89ac222 Michael Roth
                    return False
123 e89ac222 Michael Roth
            return True
124 e89ac222 Michael Roth
        return dict.__eq__(self, other)
125 e89ac222 Michael Roth
126 e89ac222 Michael Roth
    def __ne__(self, other):
127 e89ac222 Michael Roth
        return not self == other