IndexError: pop from empty list (tested)
IndexError: pop from empty list means .pop() was called on a list that had nothing left. We measured it on Python 3.13.5 alongside the messages from deque, heapq, dict and set, and the two code patterns that usually cause it.
1. The message for each container
stack = [1, 2]
stack.pop(); stack.pop()
try:
stack.pop()
except IndexError as e:
print("list.pop:", e)
try:
[1].pop(5)
except IndexError as e:
print("pop(5):", e)
from collections import deque
try:
deque().popleft()
except IndexError as e:
print("deque.popleft:", e)
import heapq
try:
heapq.heappop([])
except IndexError as e:
print("heappop:", e)
try:
{}.popitem()
except KeyError as e:
print("dict.popitem: KeyError", e)
try:
set().pop()
except KeyError as e:
print("set.pop: KeyError", e)
Output:
list.pop: pop from empty list
pop(5): pop index out of range
deque.popleft: pop from an empty deque
heappop: index out of range
dict.popitem: KeyError 'popitem(): dictionary is empty'
set.pop: KeyError 'pop from an empty set'
Measured on Python 3.13.5: list.pop() on an empty list says pop from empty list; with an index past the end it says pop index out of range. deque and heapq raise IndexError with their own wording (heappop gives just index out of range), while dict.popitem() and set.pop() raise KeyError, so an except IndexError won't catch those.
2. A stack that pops more than it pushed
def balanced(s):
stack = []
for ch in s:
if ch == "(":
stack.append(ch)
elif ch == ")":
stack.pop() # crashes on an unmatched ")"
return not stack
for s in ["(())", "())"]:
try:
print(s, balanced(s))
except IndexError as e:
print(s, "IndexError:", e)
def balanced_fixed(s):
stack = []
for ch in s:
if ch == "(":
stack.append(ch)
elif ch == ")":
if not stack:
return False
stack.pop()
return not stack
print("())", balanced_fixed("())"))
Output:
(()) True
()) IndexError: pop from empty list
()) False
Measured: the classic case: bracket matching, undo stacks, tree traversal. Input with one more closing than opening item pops an empty list. Check if not stack before popping and decide what that means (here: unbalanced).
3. Popping inside a loop
items = [1, 2, 3, 4]
for x in items: # popping while iterating skips items
items.pop(0)
print("left after loop:", items)
queue = ["a", "b", "c"]
while queue: # the safe drain loop
print("process", queue.pop(0))
item = queue.pop() if queue else None # pop with a default
print("default:", item)
Output:
left after loop: [3, 4]
process a
process b
process c
default: None
Measured: popping from the list you're iterating over with for skips items (4 items, only 2 popped). Use while queue: to drain a list, and queue.pop() if queue else None when empty is a normal case. For queues, collections.deque.popleft() is O(1) where list.pop(0) shifts every element.
Frequently asked questions
What does IndexError: pop from empty list mean?
list.pop() was called on a list with no items. We measured it, plus the related messages: pop index out of range, pop from an empty deque, and heappop's index out of range.
How do I pop from a list without an error if it's empty?
Check first: item = lst.pop() if lst else None, or loop with while lst:. We measured both on Python 3.13.5.
Why does pop from empty list happen in my stack code?
More pops than pushes, e.g. an unmatched closing bracket. We measured a balanced-brackets check crashing on '())' and the fix that returns False instead.
Does except IndexError catch dict.popitem or set.pop on empty?
No. We measured both raising KeyError ('popitem(): dictionary is empty', 'pop from an empty set').
Written with AI assistance. Measured on 2026-10-09 with Python 3.13.5 on Linux: pop on empty and short lists, deque.popleft, heapq.heappop, dict.popitem and set.pop on empty containers, a bracket-matching stack, and popping inside a for loop vs a while loop. Every block was run verbatim and its output pasted from that run. PlainHeaders is our extension; everything else here is built-in Python.