Files
2026-05-12 19:40:31 +09:00

115 lines
3.1 KiB
Python

from typing import List, Optional, TypeVar
T = TypeVar("T")
class Stack(List[T]):
_max_length: Optional[int]
def __init__(self, *args, max_length: Optional[int] = None):
initial_entries = args
if max_length:
initial_entries = initial_entries[:max_length]
super().__init__(initial_entries)
self._max_length = max_length
def empty(self) -> bool:
"""Tests if this stack is empty."""
return len(self) == 0
def peek(self) -> Optional[T]:
"""Looks at the object at the top (last/most recently added) of this
stack without removing it from the stack."""
return self.at(-1)
def pop(self) -> Optional[T]:
"""Removes the object at the top of this stack and returns that object
as the value of this function."""
try:
value = super().pop()
return value
except IndexError:
pass
def push(self, item: T) -> None:
"""Pushes an item onto the top of this stack.
Proxy of List.append
Limits Stack Length to _max_length entries
"""
self.append(item)
if self._max_length:
del self[: -self._max_length]
def search(self, x: T) -> Optional[int]:
"""Returns the 0-based position of the last item whose value is equal
to x on this stack.
We deviate from the typical 1-based position used by Stack
classes (i.e. Java) because most python users (and developers in
general) are accustomed to 0-based indexing.
"""
copy = self.copy()
copy.reverse()
try:
found_index = copy.index(x)
return len(self) - found_index - 1
except ValueError:
pass
def at(self, index: int, default: Optional[T] = None) -> Optional[T]:
"""Returns the item located at the index.
If the index does not exist in the stack (Overflow or
Underflow), None is returned instead.
"""
try:
value = self[index]
return value
except IndexError:
return default
def copy(self) -> "Stack[T]":
"""Returns a copy of the current Stack."""
copy = super().copy()
return Stack(*copy)
@property
def first(self) -> Optional[T]:
"""Returns the first item of the stack without removing it.
Same as Stack.bottom.
"""
return self.at(0)
@property
def last(self) -> Optional[T]:
"""Returns the last item of the stack without removing it.
Same as Stack.top.
"""
return self.at(-1)
@property
def bottom(self) -> Optional[T]:
"""Returns the item on the bottom of the stack without removing it.
Same as Stack.first.
"""
return self.at(0)
@property
def top(self) -> Optional[T]:
"""Returns the item on the top of the stack without removing it.
Same as Stack.last.
"""
return self.at(-1)
@property
def length(self) -> int:
"""Returns the number of items in the Stack."""
return len(self)