1 | #!/usr/bin/env python |
---|
2 | """Backport from python2.7 to python <= 2.6.""" |
---|
3 | |
---|
4 | from itertools import repeat as _repeat, chain as _chain, starmap as _starmap |
---|
5 | |
---|
6 | try: |
---|
7 | from itertools import izip_longest as _zip_longest |
---|
8 | except ImportError: |
---|
9 | |
---|
10 | from itertools import izip |
---|
11 | |
---|
12 | def _zip_longest(*args, **kwds): |
---|
13 | # izip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D- |
---|
14 | fillvalue = kwds.get('fillvalue') |
---|
15 | def sentinel(counter = ([fillvalue]*(len(args)-1)).pop): |
---|
16 | yield counter() # yields the fillvalue, or raises IndexError |
---|
17 | fillers = _repeat(fillvalue) |
---|
18 | iters = [_chain(it, sentinel(), fillers) for it in args] |
---|
19 | try: |
---|
20 | for tup in izip(*iters): |
---|
21 | yield tup |
---|
22 | except IndexError: |
---|
23 | pass |
---|
24 | |
---|
25 | class OrderedDict(dict): |
---|
26 | |
---|
27 | def __init__(self, *args, **kwds): |
---|
28 | if len(args) > 1: |
---|
29 | raise TypeError('expected at most 1 arguments, got %d' % len(args)) |
---|
30 | if not hasattr(self, '_keys'): |
---|
31 | self._keys = [] |
---|
32 | self.update(*args, **kwds) |
---|
33 | |
---|
34 | def clear(self): |
---|
35 | del self._keys[:] |
---|
36 | dict.clear(self) |
---|
37 | |
---|
38 | def __setitem__(self, key, value): |
---|
39 | if key not in self: |
---|
40 | self._keys.append(key) |
---|
41 | dict.__setitem__(self, key, value) |
---|
42 | |
---|
43 | def __delitem__(self, key): |
---|
44 | dict.__delitem__(self, key) |
---|
45 | self._keys.remove(key) |
---|
46 | |
---|
47 | def __iter__(self): |
---|
48 | return iter(self._keys) |
---|
49 | |
---|
50 | def __reversed__(self): |
---|
51 | return reversed(self._keys) |
---|
52 | |
---|
53 | def popitem(self): |
---|
54 | if not self: |
---|
55 | raise KeyError('dictionary is empty') |
---|
56 | key = self._keys.pop() |
---|
57 | value = dict.pop(self, key) |
---|
58 | return key, value |
---|
59 | |
---|
60 | def __reduce__(self): |
---|
61 | items = [[k, self[k]] for k in self] |
---|
62 | inst_dict = vars(self).copy() |
---|
63 | inst_dict.pop('_keys', None) |
---|
64 | return (self.__class__, (items,), inst_dict) |
---|
65 | |
---|
66 | def setdefault(self, key, default=None): |
---|
67 | try: |
---|
68 | return self[key] |
---|
69 | except KeyError: |
---|
70 | self[key] = default |
---|
71 | return default |
---|
72 | |
---|
73 | def update(self, other=(), **kwds): |
---|
74 | if hasattr(other, "keys"): |
---|
75 | for key in other.keys(): |
---|
76 | self[key] = other[key] |
---|
77 | else: |
---|
78 | for key, value in other: |
---|
79 | self[key] = value |
---|
80 | for key, value in kwds.items(): |
---|
81 | self[key] = value |
---|
82 | |
---|
83 | __marker = object() |
---|
84 | |
---|
85 | def pop(self, key, default=__marker): |
---|
86 | try: |
---|
87 | value = self[key] |
---|
88 | except KeyError: |
---|
89 | if default is self.__marker: |
---|
90 | raise |
---|
91 | return default |
---|
92 | else: |
---|
93 | del self[key] |
---|
94 | return value |
---|
95 | |
---|
96 | def keys(self): |
---|
97 | return list(self) |
---|
98 | |
---|
99 | def values(self): |
---|
100 | return [self[key] for key in self] |
---|
101 | |
---|
102 | def items(self): |
---|
103 | return [(key, self[key]) for key in self] |
---|
104 | |
---|
105 | def __repr__(self): |
---|
106 | if not self: |
---|
107 | return '%s()' % (self.__class__.__name__,) |
---|
108 | return '%s(%r)' % (self.__class__.__name__, list(self.items())) |
---|
109 | |
---|
110 | def copy(self): |
---|
111 | return self.__class__(self) |
---|
112 | |
---|
113 | @classmethod |
---|
114 | def fromkeys(cls, iterable, value=None): |
---|
115 | d = cls() |
---|
116 | for key in iterable: |
---|
117 | d[key] = value |
---|
118 | return d |
---|
119 | |
---|
120 | def __eq__(self, other): |
---|
121 | if isinstance(other, OrderedDict): |
---|
122 | return all(p==q for p, q in _zip_longest(self.items(), other.items())) |
---|
123 | return dict.__eq__(self, other) |
---|
124 | |
---|
125 | |
---|
126 | |
---|
127 | # End class OrderedDict |
---|
128 | |
---|