Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python
- from _abcoll import *
- import types, collections
- class xOrderedDict(dict, MutableMapping):
- # dict object are NOT accepted as arguments because they are not order-preserving
- # accepting OrderedDict, xOrderedDict, list of tuples
- def __init__(self, *args):
- self._K = []
- if args: self.update(*args)
- def __setitem__(self, key, value):
- if key not in self: self._K.append(key)
- dict.__setitem__(self, key, value)
- def __delitem__(self, keys):
- self.delete(*keys)
- def __eq__(self, other):
- if not isinstance(other, xOrderedDict): return False
- if not MutableMapping.__eq__(self, other): return False
- return self._K == other._K
- def __ne__(self, other): return not self.__eq__(other)
- def __iter__(self):
- for key in self._K: yield key
- def _get_before_index(self, before):
- if before == [0]: return 0
- elif before == [-1]: return -1
- return self.indexof(before)
- def _rawlistfromargs(self, *args):
- raw = xOrderedDict()
- for a in args:
- if isinstance(a, (types.TupleType, types.ListType)):
- for e in a: raw[e] = None
- else: raw[a] = None
- return raw
- def _rawdictfromargs(self, *args):
- raw = xOrderedDict()
- for a in args:
- if isinstance(a, (collections.OrderedDict, xOrderedDict)): raw.update([ (k,v) for k,v in a.iteritems() ])
- elif isinstance(a, types.ListType):
- for e in a: raw[e[0]] = e[1]
- elif isinstance(a, types.TupleType): raw[a[0]] = a[1]
- else: raise TypeError('Unsupported type: ' + str(type(a)))
- return raw
- def __repr__(self):
- if not self: return '{}()'.format(self.__class__.__name__)
- return '{}({!r})'.format(self.__class__.__name__, self.items())
- popitem = MutableMapping.popitem
- pop = MutableMapping.pop
- keys = MutableMapping.keys
- values = MutableMapping.values
- items = MutableMapping.items
- iterkeys = MutableMapping.iterkeys
- itervalues = MutableMapping.itervalues
- iteritems = MutableMapping.iteritems
- setdefault = MutableMapping.setdefault
- def clear(self):
- dict.clear(self)
- self._K = []
- def indexof(self, key, *default):
- if key in self: return self._K.index(key)
- if len(default) > 1: raise AttributeError('indexof: extra argument(s) after [default]')
- if not default: raise KeyError('[{0}] is not a valid key'.format(repr(key)))
- else: return default[0]
- def keyof(self, index, *default):
- # index == -1: last key
- if not isinstance(index, types.IntType): raise TypeError('list indices must be integers, not {0}'.format(type(index).__name__))
- if index == -1: index = len(self._K) - 1
- if index >=0 and index < len(self._K): return self._K[index]
- if len(default) > 1: raise AttributeError('keyof: extra argument(s) after [default]')
- if not default: raise IndexError('index ({0}) out of range'.format(index))
- else: return default[0]
- def update(self, *args):
- MutableMapping.update(self, self._rawdictfromargs(*args))
- def copy(self): return xOrderedDict(self)
- def delete(self, *args):
- raw = self._rawlistfromargs(*args)
- unknowns = set(raw) - set(self)
- if unknowns: raise KeyError('Invalid key(s): {!r}'.format(list(unknowns)))
- for key in raw:
- dict.__delitem__(self, key)
- self._K.remove(key)
- def insert(self, before, *args):
- # if before is [-1] - append item(s) to end, if [0] - insert into beginning
- idx = self._get_before_index(before)
- raw = self._rawdictfromargs(*args)
- intersect = set(self) & set(raw)
- if intersect: raise KeyError('Duplicate key(s): {!r}'.format(list(intersect)))
- for k,v in raw.iteritems():
- dict.__setitem__(self, k, v)
- if idx != -1:
- self._K.insert(idx, k)
- idx += 1
- else: self._K.append(k)
- def move(self, before, *args):
- # if before is [-1] - move item(s) to end, if [0] - move into beginning
- idx = self._get_before_index(before)
- raw = self._rawlistfromargs(*args)
- unknowns = set(raw) - set(self)
- if unknowns: raise KeyError('Invalid key(s): {!r}'.format(list(unknowns)))
- if idx != -1 and idx in [ self._K.index(k) for k in raw.iterkeys() ]:
- raise KeyError('anchor element can not be moved')
- delta = 0
- for k in raw.iterkeys():
- i = self._K.index(k)
- if idx != -1:
- if i < idx + delta: delta -= 1
- del self._K[i]
- if idx != -1:
- self._K.insert(idx+delta, k)
- delta += 1
- else: self._K.append(k)
Advertisement
Add Comment
Please, Sign In to add comment