The list.pop() method removes one element by index and returns that object in one step. With no argument it removes the last item, which matches how people search for “python list pop” or “pop from list.” This guide stays on pop() only: syntax, last and indexed pops, pop(0), negative indices, errors, bulk patterns, cost, and how pop() differs from remove(), del, and clear().
For list basics (create, index, slice), see Python list with examples. For deleting by value without pop, see Remove element from list in Python. For catching runtime errors, see Python try except.
Tested on: Python 3.13.3; kernel 6.14.0-37-generic.
What does pop() do in Python list?
list.pop([i]) removes the item at index i, returns it, and mutates the same list object. If you omit i, Python uses -1 (the last element). The list becomes shorter by one. If the index is invalid or the list is empty, Python raises IndexError.
Python list pop() syntax
In Python, list.pop accepts at most one optional positional argument: the index to remove. There is no keyword-only API—call it as lst.pop() or lst.pop(i).
list.pop() # remove and return last item (same as pop(-1))
list.pop(i) # remove and return item at index iThe argument must be an integer index (or omitted). You cannot pass the value to delete; that is what remove is for. Negative indices follow the same rules as indexing: -1 is the last element before the pop, -len(lst) is the first, and values outside that range fail.
A minimal end-to-end example:
data = ["a", "b", "c"]
last = data.pop()
second = data.pop(1)
print(last, second, data)That prints c, b, and ['a']: each call shortens data before the next index is interpreted.
Remove and return the last item using pop()
Calling pop() with no argument removes the tail and returns it:
nums = [1, 2, 3, 4, 5]
tail = nums.pop()
print(tail, nums)That prints 5 and [1, 2, 3, 4].
Pop item from a list by index
Pass a non-negative index to remove that position (0-based):
nums = [10, 20, 30, 40, 50]
middle = nums.pop(2)
print(middle, nums)That prints 30 and [10, 20, 40, 50]—the element that used to sit at index 2 is gone and following items shift left.
Pop the first item using pop(0)
Index 0 is the head of the list:
queue = ["first", "second", "third"]
head = queue.pop(0)
print(head, queue)That prints first and ['second', 'third']. This is correct but costly on huge lists because every remaining item moves one index left; see the complexity section below.
Pop item using negative index
Negative indices count from the end: -1 is the last element, -2 the second last, before the pop runs:
letters = ["a", "b", "c", "d"]
letters.pop(-2)
print(letters)That removes c (second from the right at the time of the call), leaving ['a', 'b', 'd'].
Store the popped item in a variable
Because pop() returns the value, you can chain logic or store it:
stack = [1, 2, 3]
while stack:
item = stack.pop()
print("popped", item)Each iteration removes from the end until the list is empty; the last line printed is popped 1.
Pop item by value: should you use pop() or remove()?
pop() works by index, not by searching for a value. To delete by value you normally call remove(x) (first match only, returns None) or combine index with pop:
items = ["a", "b", "c", "b"]
items.remove("b")
print(items)
nums = [10, 20, 30]
i = nums.index(20)
gone = nums.pop(i)
print(gone, nums)That prints ['a', 'c', 'b'] then 20 and [10, 30]. Use pop() when position matters or you need the returned object; use remove() when you only know the value and do not need the return.
Pop multiple items from a list
There is no pop(count) overload; you loop or slice. Choose based on whether you need each returned value.
Pop last N items
Repeated tail pop() is simple and O(1) per pop:
nums = list(range(1, 8))
for _ in range(3):
nums.pop()
print(nums)That leaves [1, 2, 3, 4] after removing 7, 6, and 5.
Pop first N items
Repeated pop(0) works but costs O(n) per pop because of shifting; for large N consider collections.deque.popleft() or a slice assignment instead of many pop(0) calls.
nums = [1, 2, 3, 4, 5]
for _ in range(2):
nums.pop(0)
print(nums)That prints [3, 4, 5].
IndexError with list pop()
IndexError is the normal failure mode when the list has no items at the index you request. Typical fixes: check len(lst), compare the index to valid bounds, or catch the exception when the situation is expected (see Python try except).
pop from empty list
With no elements, there is no “last” item to return:
[].pop()IndexError: pop from empty listGuard before popping, for example if lst: x = lst.pop() or if len(lst) >= 1:.
pop index out of range
Positive or negative indices must still point at a real slot after Python normalizes negatives to len + index. Asking for index 10 on a three-item list fails the same way as an overly negative index:
[1, 2, 3].pop(10)IndexError: pop index out of range[1, 2].pop(-3)IndexError: pop index out of rangeFor length n, valid indices are 0 through n - 1, or -n through -1 inclusive. A small helper keeps callers safe when the index might be invalid:
def safe_pop(seq, index=-1):
try:
return seq.pop(index)
except IndexError:
return None
print(safe_pop([1], 5))
print(safe_pop([]))That prints None twice without crashing.
list.pop() vs remove() vs del vs clear()
| Mechanism | Selects by | Returns removed value? | Notes |
|---|---|---|---|
pop(i) |
Index (default last) | Yes | Shortens list by one |
remove(x) |
First value equal to x |
No (None) |
Raises ValueError if missing |
del lst[i] or del lst[a:b] |
Index or slice | No | Slice delete can remove many at once |
clear() |
Entire list | No | Empties the list |
Use del lst[i:j] when you want to drop a slice without needing each returned element.
Time complexity of list pop()
Python lists are implemented as contiguous dynamic arrays of object pointers. When you delete index i, the interpreter closes the gap by moving every reference that used to sit to the right of i one slot left. The number of pointer moves is exactly the length of that tail segment.
If n is the list length before pop, a successful pop(i) moves n - i - 1 references (zero when i is the last index). That is why cost is linear in the tail size, not a vague “sometimes linear.”
def references_moved(n, i):
"""How many items slide left after pop at valid index i (len == n before pop)."""
return n - i - 1
print(references_moved(6, 2))
print(references_moved(6, 0))
print(references_moved(6, 5))That prints 3, 5, and 0: popping the middle moves three cells; popping the head moves five; popping the last moves none.
pop() from end is O(1)
Calling pop() with no argument (or pop(-1), or pop(len(lst) - 1)) drops the last slot. Here n - i - 1 is n - (n - 1) - 1 = 0, so nothing slides. CPython implements that path in amortized constant time—the usual case for stack-style code.
pop(i) for an arbitrary index
The references_moved formula is the right mental model: popping near the end touches few elements; popping near the start touches almost the whole list. Worst case for a single pop on a length-n list is therefore Theta(n) when i == 0, and best case Theta(1) when i == n - 1.
pop(0) from front is O(n)
pop(0) always moves n - 1 references. Repeating it until the list is empty does work proportional to (n-1) + (n-2) + ... + 1, which is Theta(n^2) overall. For FIFO queues at scale, collections.deque and popleft() keep left-end removal at amortized O(1) per step instead.
Rough timing: tail vs head (illustration)
Absolute numbers depend on hardware and Python build, but the order of magnitude gap is stable: with a long list, one pop(0) does far more work than one tail pop() because of the memmove.
import timeit
n = 200_000
tail = timeit.timeit("xs.pop()", setup=f"xs = list(range({n}))", number=500)
head = timeit.timeit("xs.pop(0)", setup=f"xs = list(range({n}))", number=50)
print(round((head / 50) / (tail / 500), 0))On the machine used to refresh this article, that ratio was in the hundreds to low thousands—large enough that micro-benchmarks are noisy, but the lesson stays the same: avoid a hot pop(0) loop on massive lists when you need FIFO behavior.
| Call pattern | Typical time (n = len before pop) | Why |
|---|---|---|
pop() / pop(-1) |
O(1) amortized |
n - i - 1 is 0 |
pop(i) |
Theta(n - i - 1) |
Tail memmove |
pop(0) |
Theta(n) |
Whole tail shifts by one |
Common mistakes with list pop()
- Calling
pop()on an empty list: guard withif lst:or handleIndexErrorwhen length is uncertain. - Passing a value to
popas if it wereremove: useremove, orlst.index(x)thenpop, withValueErrorhandled ifxmight be missing. - Using
pop(0)in a tight loop on a large list when adequeor index cursor would scale better. - Forgetting that
popmutates the list whilelst[i]only reads; usex = lst.pop()when you need the removed object.
Python list pop() quick reference table
| Call | Removes | Returns | Typical error |
|---|---|---|---|
lst.pop() |
Last item | That item | IndexError if empty |
lst.pop(0) |
First item | That item | IndexError if empty |
lst.pop(-1) |
Same as no-arg | Last item | IndexError if empty |
lst.pop(k) |
Index k |
That item | IndexError if k out of range |
Summary
list.pop() is indexed removal that returns the element: no argument pops the last item; pop(0) pops the first; negative indices count from the end. Cost is cheap at the tail because no slots slide; at index i about n - i - 1 references move, so the head is worst-case linear and draining the list with repeated pop(0) is quadratic overall. Use it when position matters or you need the value back; use remove() for first match by value with no return; use del for slices or when you do not need the object returned; use clear() to drop everything. Watch IndexError on empty or out-of-range pops; for many left-end removals on large data, prefer a deque over repeated pop(0).

