from collections import OrderedDict from typing import Generic, TypeVar K = TypeVar("K") V = TypeVar("V") class LRUCache(Generic[K, V]): """A fixed-capacity least-recently-used cache.""" def __init__(self, capacity: int) -> None: if capacity <= 0: raise ValueError("capacity must be positive") self.capacity = capacity self._items: OrderedDict[K, V] = OrderedDict() def get(self, key: K) -> V: """Return a value and mark its key as recently used.""" value = self._items.pop(key) self._items[key] = value return value def put(self, key: K, value: V) -> None: """Insert or update a value, evicting the oldest if necessary.""" if key in self._items: self._items.pop(key) self._items[key] = value if len(self._items) > self.capacity: self._items.popitem(last=False) def __contains__(self, key: object) -> bool: return key in self._items def __len__(self) -> int: return len(self._items) def main() -> None: cache: LRUCache[str, int] = LRUCache(2) cache.put("a", 1) cache.put("b", 2) cache.put("c", 3) assert "a" not in cache and cache.get("c") == 3 cache.get("b") # Refresh "b", making "c" the least recently used. cache.put("d", 4) assert "c" not in cache and cache.get("b") == 2 if __name__ == "__main__": main()