collections.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. from typing import Generic, TypeVar, Iterable
  2. T = TypeVar('T')
  3. def Counter(iterable: Iterable[T]):
  4. a: dict[T, int] = {}
  5. for x in iterable:
  6. if x in a:
  7. a[x] += 1
  8. else:
  9. a[x] = 1
  10. return a
  11. class defaultdict(dict):
  12. def __init__(self, default_factory, *args):
  13. super().__init__(*args)
  14. self.default_factory = default_factory
  15. def __missing__(self, key):
  16. self[key] = self.default_factory()
  17. return self[key]
  18. def __repr__(self) -> str:
  19. return f"defaultdict({self.default_factory}, {super().__repr__()})"
  20. def copy(self):
  21. return defaultdict(self.default_factory, self)
  22. class deque(Generic[T]):
  23. _data: list[T]
  24. _head: int
  25. _tail: int
  26. _capacity: int
  27. def __init__(self, iterable: Iterable[T] = None):
  28. self._data = [None] * 8 # initial capacity
  29. self._head = 0
  30. self._tail = 0
  31. self._capacity = len(self._data)
  32. if iterable is not None:
  33. self.extend(iterable)
  34. def __resize_2x(self):
  35. backup = list(self)
  36. self._capacity *= 2
  37. self._head = 0
  38. self._tail = len(backup)
  39. self._data.clear()
  40. self._data.extend(backup)
  41. self._data.extend([None] * (self._capacity - len(backup)))
  42. def append(self, x: T):
  43. self._data[self._tail] = x
  44. self._tail = (self._tail + 1) % self._capacity
  45. if (self._tail + 1) % self._capacity == self._head:
  46. self.__resize_2x()
  47. def appendleft(self, x: T):
  48. self._head = (self._head - 1 + self._capacity) % self._capacity
  49. self._data[self._head] = x
  50. if (self._tail + 1) % self._capacity == self._head:
  51. self.__resize_2x()
  52. def copy(self):
  53. return deque(self)
  54. def count(self, x: T) -> int:
  55. n = 0
  56. for item in self:
  57. if item == x:
  58. n += 1
  59. return n
  60. def extend(self, iterable: Iterable[T]):
  61. for x in iterable:
  62. self.append(x)
  63. def extendleft(self, iterable: Iterable[T]):
  64. for x in iterable:
  65. self.appendleft(x)
  66. def pop(self) -> T:
  67. if self._head == self._tail:
  68. raise IndexError("pop from an empty deque")
  69. self._tail = (self._tail - 1 + self._capacity) % self._capacity
  70. return self._data[self._tail]
  71. def popleft(self) -> T:
  72. if self._head == self._tail:
  73. raise IndexError("pop from an empty deque")
  74. x = self._data[self._head]
  75. self._head = (self._head + 1) % self._capacity
  76. return x
  77. def clear(self):
  78. i = self._head
  79. while i != self._tail:
  80. self._data[i] = None
  81. i = (i + 1) % self._capacity
  82. self._head = 0
  83. self._tail = 0
  84. def rotate(self, n: int = 1):
  85. if len(self) == 0:
  86. return
  87. if n > 0:
  88. n = n % len(self)
  89. for _ in range(n):
  90. self.appendleft(self.pop())
  91. elif n < 0:
  92. n = -n % len(self)
  93. for _ in range(n):
  94. self.append(self.popleft())
  95. def __len__(self) -> int:
  96. return (self._tail - self._head + self._capacity) % self._capacity
  97. def __contains__(self, x: object) -> bool:
  98. for item in self:
  99. if item == x:
  100. return True
  101. return False
  102. def __iter__(self):
  103. i = self._head
  104. while i != self._tail:
  105. yield self._data[i]
  106. i = (i + 1) % self._capacity
  107. def __eq__(self, other: object) -> bool:
  108. if not isinstance(other, deque):
  109. return NotImplemented
  110. if len(self) != len(other):
  111. return False
  112. for x, y in zip(self, other):
  113. if x != y:
  114. return False
  115. return True
  116. def __ne__(self, other: object) -> bool:
  117. if not isinstance(other, deque):
  118. return NotImplemented
  119. return not self == other
  120. def __repr__(self) -> str:
  121. return f"deque({list(self)!r})"