mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-19 19:10:17 +00:00
add maxlen for deque
This commit is contained in:
parent
d3d61dde0c
commit
f12a379760
@ -27,20 +27,29 @@ class defaultdict(dict):
|
||||
|
||||
|
||||
class deque[T]:
|
||||
_data: list[T]
|
||||
_head: int
|
||||
_tail: int
|
||||
_maxlen: int | None
|
||||
_capacity: int
|
||||
_data: list[T]
|
||||
|
||||
def __init__(self, iterable: Iterable[T] = None, maxlen: int | None = None):
|
||||
if maxlen is not None:
|
||||
assert maxlen > 0
|
||||
|
||||
def __init__(self, iterable: Iterable[T] = None):
|
||||
self._data = [None] * 8 # type: ignore
|
||||
self._head = 0
|
||||
self._tail = 0
|
||||
self._capacity = len(self._data)
|
||||
self._maxlen = maxlen
|
||||
self._capacity = 8 if maxlen is None else maxlen + 1
|
||||
self._data = [None] * self._capacity # type: ignore
|
||||
|
||||
if iterable is not None:
|
||||
self.extend(iterable)
|
||||
|
||||
@property
|
||||
def maxlen(self) -> int | None:
|
||||
return self._maxlen
|
||||
|
||||
def __resize_2x(self):
|
||||
backup = list(self)
|
||||
self._capacity *= 2
|
||||
@ -51,19 +60,25 @@ class deque[T]:
|
||||
self._data.extend([None] * (self._capacity - len(backup)))
|
||||
|
||||
def append(self, x: T):
|
||||
if (self._tail + 1) % self._capacity == self._head:
|
||||
if self._maxlen is None:
|
||||
self.__resize_2x()
|
||||
else:
|
||||
self.popleft()
|
||||
self._data[self._tail] = x
|
||||
self._tail = (self._tail + 1) % self._capacity
|
||||
if (self._tail + 1) % self._capacity == self._head:
|
||||
self.__resize_2x()
|
||||
|
||||
def appendleft(self, x: T):
|
||||
if (self._tail + 1) % self._capacity == self._head:
|
||||
if self._maxlen is None:
|
||||
self.__resize_2x()
|
||||
else:
|
||||
self.pop()
|
||||
self._head = (self._head - 1) % self._capacity
|
||||
self._data[self._head] = x
|
||||
if (self._tail + 1) % self._capacity == self._head:
|
||||
self.__resize_2x()
|
||||
|
||||
def copy(self):
|
||||
return deque(self)
|
||||
return deque(self, maxlen=self.maxlen)
|
||||
|
||||
def count(self, x: T) -> int:
|
||||
n = 0
|
||||
@ -84,12 +99,15 @@ class deque[T]:
|
||||
if self._head == self._tail:
|
||||
raise IndexError("pop from an empty deque")
|
||||
self._tail = (self._tail - 1) % self._capacity
|
||||
return self._data[self._tail]
|
||||
x = self._data[self._tail]
|
||||
self._data[self._tail] = None
|
||||
return x
|
||||
|
||||
def popleft(self) -> T:
|
||||
if self._head == self._tail:
|
||||
raise IndexError("pop from an empty deque")
|
||||
x = self._data[self._head]
|
||||
self._data[self._head] = None
|
||||
self._head = (self._head + 1) % self._capacity
|
||||
return x
|
||||
|
||||
@ -144,5 +162,7 @@ class deque[T]:
|
||||
return not self == other
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"deque({list(self)!r})"
|
||||
if self.maxlen is None:
|
||||
return f"deque({list(self)!r})"
|
||||
return f"deque({list(self)!r}, maxlen={self.maxlen})"
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
@ -516,3 +516,31 @@ d = deque()
|
||||
for i in range(100):
|
||||
d.append(1)
|
||||
gc.collect()
|
||||
|
||||
# test maxlen
|
||||
q = deque(maxlen=3)
|
||||
assertEqual(q.maxlen, 3)
|
||||
q.append(1)
|
||||
q.append(2)
|
||||
q.append(3)
|
||||
assertEqual(list(q), [1, 2, 3])
|
||||
assertEqual(q._data, [1, 2, 3, None])
|
||||
q.append(4)
|
||||
assertEqual(list(q), [2, 3, 4])
|
||||
assertEqual(q._data, [None, 2, 3, 4])
|
||||
q.appendleft(1)
|
||||
assertEqual(list(q), [1, 2, 3])
|
||||
assertEqual(q._data, [1, 2, 3, None])
|
||||
q.appendleft(0)
|
||||
assertEqual(list(q), [0, 1, 2])
|
||||
assertEqual(q._data, [1, 2, None, 0])
|
||||
q.pop()
|
||||
assertEqual(list(q), [0, 1])
|
||||
assertEqual(q._data, [1, None, None, 0])
|
||||
assertEqual(len(q), 2)
|
||||
assertEqual(q._capacity, 4)
|
||||
q.popleft()
|
||||
assertEqual(list(q), [1])
|
||||
assertEqual(q._data, [1, None, None, None])
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user