collections.py 3.9 KB

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