krahets/hello-algo · error · IndexError

двусторонняя очередь пуста

Error message

двусторонняя очередь пуста

What it means

Raised by ArrayDeque.peek_first() in chapter_stack_and_queue/array_deque.py:76 — IndexError("двусторонняя очередь пуста" = "deque is empty"). peek_first reads self._nums[self._front]; on an empty deque _front may point at a stale slot, so the guard is required to avoid returning garbage. pop_first() internally calls peek_first(), so it propagates the same error when empty.

Source

Thrown at ru/codes/python/chapter_stack_and_queue/array_deque.py:76

    def pop_first(self) -> int:
        """Извлечение из головы очереди"""
        num = self.peek_first()
        # Указатель головы сдвигается на одну позицию назад
        self._front = self.index(self._front + 1)
        self._size -= 1
        return num

    def pop_last(self) -> int:
        """Извлечение из хвоста очереди"""
        num = self.peek_last()
        self._size -= 1
        return num

    def peek_first(self) -> int:
        """Доступ к элементу в начале очереди"""
        if self.is_empty():
            raise IndexError("двусторонняя очередь пуста")
        return self._nums[self._front]

    def peek_last(self) -> int:
        """Доступ к элементу в конце очереди"""
        if self.is_empty():
            raise IndexError("двусторонняя очередь пуста")
        # Вычислить индекс хвостового элемента
        last = self.index(self._front + self._size - 1)
        return self._nums[last]

    def to_array(self) -> list[int]:
        """Вернуть массив для вывода"""
        # Преобразовывать только элементы списка в пределах фактической длины
        res = []
        for i in range(self._size):
            res.append(self._nums[self.index(self._front + i)])
        return res

View on GitHub (pinned to 69932aed18)

Solutions

  1. Guard: if not dq.is_empty(): dq.peek_first().
  2. Make is_empty() the loop condition for draining.
  3. Use pop_first's delegation: catch IndexError at the call site if best-effort.
  4. Track expected element count upstream so pop is never called on empty.

Example fix

// before
x = dq.peek_first()
// after
x = dq.peek_first() if not dq.is_empty() else None
Defensive patterns

Strategy: validation

Validate before calling

def safe_peek_first(dq):
    return dq.peek_first() if not dq.is_empty() else None

Type guard

def deque_non_empty(dq) -> bool:
    return not dq.is_empty()

Try / catch

try:
    x = dq.peek_first()
except IndexError:
    x = None

Prevention

When it happens

Trigger: Calling peek_first() (or pop_first(), which delegates to it) on an empty deque. Draining the deque with repeated pop_first without checking is_empty().

Common situations: Unbalanced push/pop counts. Processing a stream that yields no elements before the first pop. Reusing a deque across batches without resetting size checks.

Related errors


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