krahets/hello-algo · error · IndexError

куча пуста

Error message

куча пуста

What it means

Raised by MaxHeap.pop() in chapter_heap/my_heap.py:77 — IndexError("куча пуста" = "heap is empty"). pop() swaps the root with the last leaf, removes the last element, then sifts down to restore the heap property. It refuses to operate on an empty heap because there is no root to extract.

Source

Thrown at ru/codes/python/chapter_heap/my_heap.py:77

    def sift_up(self, i: int):
        """Начиная с узла i, выполнить просеивание снизу вверх"""
        while True:
            # Получение родительского узла для узла i
            p = self.parent(i)
            # Завершить heapify, когда «корневой узел уже пройден» или «узел не требует исправления»
            if p < 0 or self.max_heap[i] <= self.max_heap[p]:
                break
            # Поменять два узла местами
            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 = r

View on GitHub (pinned to 69932aed18)

Solutions

  1. Guard: while not heap.is_empty(): heap.pop().
  2. Check heap.size() > 0 before a single pop.
  3. In a sort/drain loop, make is_empty() the loop condition.
  4. Wrap pop() in try/except IndexError for optional extraction.

Example fix

// before
val = heap.pop()
// after
if not heap.is_empty():
    val = heap.pop()
else:
    val = None
Defensive patterns

Strategy: validation

Validate before calling

def safe_pop(heap):
    return heap.pop() if not heap.is_empty() else None

Type guard

def heap_has_elements(heap) -> bool:
    return heap.size() > 0

Try / catch

try:
    val = heap.pop()
except IndexError:
    val = None

Prevention

When it happens

Trigger: Calling pop() more times than elements were pushed. Calling pop() on a freshly constructed heap. Calling pop() in a draining loop (e.g. heap sort) without an is_empty() termination check.

Common situations: See trigger scenarios.

Related errors


AI-assisted analysis of krahets/hello-algo@69932aed18 (2026-08-13). Data as JSON: /api/errors/b82803fee278feea. Report an issue: GitHub.