krahets/hello-algo · error · IndexError
ヒープが空です
Error message
ヒープが空です
What it means
This IndexError (Japanese: 'ヒープが空です' = 'heap is empty') is raised by MaxHeap.pop() (my_heap.py:77) when the heap contains no elements. pop() swaps the root with the last leaf, removes the last element, then sifts down — all of which would crash on an empty list, so the guard prevents that. MaxHeap is a teaching max-heap built on a plain Python list.
Source
Thrown at ja/codes/python/chapter_heap/my_heap.py:77
def sift_up(self, i: int):
"""ノード i から始めて、下から上へヒープ化"""
while True:
# ノード i の親ノードを取得
p = self.parent(i)
# 「根ノードを越えた」または「ノードの修復が不要」になったらヒープ化を終了
if p < 0 or self.max_heap[i] <= self.max_heap[p]:
break
# 2 つのノードを交換
self.swap(i, p)
# ループで下から上へヒープ化
i = p
def pop(self) -> int:
"""要素をヒープから取り出す"""
# 空判定の処理
if self.is_empty():
raise IndexError("ヒープが空です")
# 根ノードと最も右の葉ノードを交換(先頭要素と末尾要素を交換)
self.swap(0, self.size() - 1)
# ノードを削除
val = self.max_heap.pop()
# 上から下へヒープ化
self.sift_down(0)
# ヒープ先頭要素を返す
return val
def sift_down(self, i: int):
"""ノード i から始めて、上から下へヒープ化"""
while True:
# ノード i, l, r のうち値が最大のノードを ma とする
l, r, ma = self.left(i), self.right(i), i
if l < self.size() and self.max_heap[l] > self.max_heap[ma]:
ma = l
if r < self.size() and self.max_heap[r] > self.max_heap[ma]:
ma = rView on GitHub (pinned to 69932aed18)
Solutions
- Check `if not heap.is_empty(): heap.pop()` before each pop.
- Loop with `while not heap.is_empty():` as the drain condition.
- Guard the constructor input: if the source list is empty, skip heap operations.
- Count pops against heap.size() to avoid over-draining.
Example fix
// before
while True:
top = heap.pop() # IndexError when drained
// after
while not heap.is_empty():
top = heap.pop() Defensive patterns
Strategy: validation
Validate before calling
if not heap.is_empty():
val = heap.pop() Type guard
def heap_has_top(heap: MaxHeap) -> bool:
return not heap.is_empty() Try / catch
try:
val = heap.pop()
except IndexError:
# heap was empty
val = None Prevention
- Drain with `while not heap.is_empty():` rather than a fixed iteration count.
- Guard pop() with is_empty() every time.
- Validate the constructor input list is non-empty before heap operations.
- Count pops against heap.size() to prevent over-draining.
When it happens
Trigger: Calling pop() on a MaxHeap constructed from an empty list `MaxHeap([])`. Calling pop() more times than elements were pushed. Calling pop() after draining the heap in a loop without an is_empty() check.
Common situations: Draining a heap in `while True: heap.pop()` without a termination guard. Building a heap from filtered/empty input data. Off-by-one in a loop that pops n+1 times from an n-element heap.
Related errors
AI-assisted analysis of krahets/hello-algo@69932aed18 (2026-08-13).
Data as JSON: /api/errors/fbe663e2d53c01d5.
Report an issue: GitHub.