Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ordDict.py 4.2KB

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