{"record":{"id":"159f7c1e7aa41155","repo":"krahets/hello-algo","slug":"error-159f7c","errorCode":null,"errorMessage":"雙向佇列為空","messagePattern":"雙向佇列為空","errorType":"exception","errorClass":"IndexError","httpStatus":null,"severity":"error","filePath":"zh-hant/codes/python/chapter_stack_and_queue/linkedlist_deque.py","lineNumber":66,"sourceCode":"        else:\n            # 將 node 新增至鏈結串列尾部\n            self._rear.next = node\n            node.prev = self._rear\n            self._rear = node  # 更新尾節點\n        self._size += 1  # 更新佇列長度\n\n    def push_first(self, num: int):\n        \"\"\"佇列首入列\"\"\"\n        self.push(num, True)\n\n    def push_last(self, num: int):\n        \"\"\"佇列尾入列\"\"\"\n        self.push(num, False)\n\n    def pop(self, is_front: bool) -> int:\n        \"\"\"出列操作\"\"\"\n        if self.is_empty():\n            raise IndexError(\"雙向佇列為空\")\n        # 佇列首出列操作\n        if is_front:\n            val: int = self._front.val  # 暫存頭節點值\n            # 刪除頭節點\n            fnext: ListNode | None = self._front.next\n            if fnext is not None:\n                fnext.prev = None\n                self._front.next = None\n            self._front = fnext  # 更新頭節點\n        # 佇列尾出列操作\n        else:\n            val: int = self._rear.val  # 暫存尾節點值\n            # 刪除尾節點\n            rprev: ListNode | None = self._rear.prev\n            if rprev is not None:\n                rprev.next = None\n                self._rear.prev = None\n            self._rear = rprev  # 更新尾節點","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/krahets/hello-algo/blob/69932aed1891a7b7f6a0de88cd116d3fe13e7032/zh-hant/codes/python/chapter_stack_and_queue/linkedlist_deque.py#L48-L84","documentation":"Raised by the internal pop(is_front) method of a doubly-linked-list-based deque when the deque has zero nodes. This method is called by both pop_first() (is_front=True) and pop_last() (is_front=False), so both public methods inherit the guard. The check tests is_empty() before attempting to dereference _front or _rear pointers.","triggerScenarios":"Calling pop_first() or pop_last() on a freshly constructed LinkedListDeque; draining from both ends until empty and then popping once more; calling pop() after a failed push that silently returned.","commonSituations":"Two-ended draining algorithms (palindrome checks, window processing); BFS/DFS deques that exhaust all nodes; testing with empty initial sequences.","solutions":["Check deque.is_empty() before calling pop_first() or pop_last()","Use size() as the loop bound in dual-ended draining","Wrap in try/except IndexError for defensive deque operations"],"exampleFix":"# before\nval = deque.pop_first()\n\n# after\nval = deque.pop_first() if not deque.is_empty() else None","handlingStrategy":"validation","validationCode":"if not deque.is_empty():\n    val = deque.pop_first()\nelse:\n    val = None","typeGuard":null,"tryCatchPattern":"try:\n    val = deque.pop_last()\nexcept IndexError:\n    val = None","preventionTips":["Check is_empty() before pop_first() or pop_last()","Both pop methods share the same internal pop(is_front) guard","Track size() in dual-ended draining to know when to stop"],"tags":["data-structure","deque","python","linked-list"],"backgroundTag":null,"analyzedSha":"69932aed1891a7b7f6a0de88cd116d3fe13e7032","analyzedAt":"2026-08-13T23:02:37.581Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}