1def get(self, key: int) -> int:
2 if key not in self.cache: # miss
3 return -1
4 node = self.cache[key] # O(1)
5 self._remove(node) # unlink
6 self._insert(node) # → front
7 return node.val
8
9def put(self, key: int, val: int):
10 if key in self.cache:
11 self._remove(self.cache[key])
12 node = Node(key, val)
13 self.cache[key] = node # HashMap
14 self._insert(node) # → front
15 if len(self.cache) > self.cap:
16 lru = self.tail.prev # LRU node
17 self._remove(lru) # evict DLL
18 del self.cache[lru.key]# evict map
19
20def _remove(self, node):
21 node.prev.next = node.next
22 node.next.prev = node.prev
23
24def _insert(self, node): # after HEAD
25 node.prev = self.head
26 node.next = self.head.next
27 self.head.next.prev = node
28 self.head.next = node