deque.popleft() is faster than list.pop(0), because the deque has been optimized to do popleft() approximately in O(1), while list.pop(0) takes O(n) (see deque objects).

Comments and code in _collectionsmodule.c for deque and listobject.c for list provide implementation insights to explain the performance differences. Namely that a deque object "is composed of a doubly-linked list", which effectively optimizes appends and pops at both ends, while list objects are not even singly-linked lists but C arrays (of pointers to elements (see Python 2.7 listobject.h#l22 and Python 3.5 listobject.h#l23), which makes them good for fast random access of elements but requires O(n) time to reposition all elements after removal of the first.

For Python 2.7 and 3.5, the URLs of these source code files are:

  1. https://hg.python.org/cpython/file/2.7/Modules/_collectionsmodule.c

  2. https://hg.python.org/cpython/file/2.7/Objects/listobject.c

  3. https://hg.python.org/cpython/file/3.5/Modules/_collectionsmodule.c

  4. https://hg.python.org/cpython/file/3.5/Objects/listobject.c

Using %timeit, the performance difference between deque.popleft() and list.pop(0) is about a factor of 4 when both the deque and the list have the same 52 elements and grows to over a factor of 1000 when their lengths are 10**8. Test results are given below.

import string
from collections import deque

%timeit d = deque(string.letters); d.popleft()
1000000 loops, best of 3: 1.46 µs per loop

%timeit d = deque(string.letters)
1000000 loops, best of 3: 1.4 µs per loop

%timeit l = list(string.letters); l.pop(0)
1000000 loops, best of 3: 1.47 µs per loop

%timeit l = list(string.letters);
1000000 loops, best of 3: 1.22 µs per loop

d = deque(range(100000000))

%timeit d.popleft()
10000000 loops, best of 3: 90.5 ns per loop

l = range(100000000)

%timeit l.pop(0)
10 loops, best of 3: 93.4 ms per loop
Answer from user4322779 on Stack Overflow
🌐
GeeksforGeeks
geeksforgeeks.org › python › deque-in-python
Deque in Python - GeeksforGeeks
remove(value): Removes the first occurrence of the specified value from the deque. If value is not found, it raises a ValueError. pop(): Removes and returns an element from the right end. popleft(): Removes and returns an element from the left end.
Published   December 11, 2025
🌐
Python
docs.python.org › 3 › library › collections.html
collections — Container datatypes
The rotate() method provides a way to implement deque slicing and deletion. For example, a pure Python implementation of del d[n] relies on the rotate() method to position elements to be popped: def delete_nth(d, n): d.rotate(-n) d.popleft() d.rotate(n)
Discussions

popleft() issues...
Lists can't popleft. A deque can. from collections import deque t1 = ["oak", 1963, "NW corner"] t2 = ["pine", 1975, "NE corner"] t3 = ["elm", 1982, "SW corner"] t4 = ["maple", 1992, "SE corner"] trees = deque([t1, t2, t3, t4]) print(trees.popleft()) More on reddit.com
🌐 r/learnpython
7
4
July 2, 2019
Is popleft() faster than pop(0) ?

Yes. list.pop(0) is O(n), and deque.popleft() is O(1).

More on reddit.com
🌐 r/learnpython
9
6
May 14, 2020
Deque.append() should return popped item - Ideas - Discussions on Python.org
If a deque is used with a fixed size, appending to one end will pop from the other end. However, there’s currently no way to reference this popped item. If I want to use it as a FIFO, I need to make sure that I pop from … More on discuss.python.org
🌐 discuss.python.org
1
November 19, 2024
python - list.pop() and deque.pop() -- is there a performance difference? - Stack Overflow
Deques are designed to optimize pushing and popping from either end, so both popleft() and popright() are O(1). ... A python deque is implemented as a doubly linked list . More on stackoverflow.com
🌐 stackoverflow.com
Top answer
1 of 3
72

deque.popleft() is faster than list.pop(0), because the deque has been optimized to do popleft() approximately in O(1), while list.pop(0) takes O(n) (see deque objects).

Comments and code in _collectionsmodule.c for deque and listobject.c for list provide implementation insights to explain the performance differences. Namely that a deque object "is composed of a doubly-linked list", which effectively optimizes appends and pops at both ends, while list objects are not even singly-linked lists but C arrays (of pointers to elements (see Python 2.7 listobject.h#l22 and Python 3.5 listobject.h#l23), which makes them good for fast random access of elements but requires O(n) time to reposition all elements after removal of the first.

For Python 2.7 and 3.5, the URLs of these source code files are:

  1. https://hg.python.org/cpython/file/2.7/Modules/_collectionsmodule.c

  2. https://hg.python.org/cpython/file/2.7/Objects/listobject.c

  3. https://hg.python.org/cpython/file/3.5/Modules/_collectionsmodule.c

  4. https://hg.python.org/cpython/file/3.5/Objects/listobject.c

Using %timeit, the performance difference between deque.popleft() and list.pop(0) is about a factor of 4 when both the deque and the list have the same 52 elements and grows to over a factor of 1000 when their lengths are 10**8. Test results are given below.

import string
from collections import deque

%timeit d = deque(string.letters); d.popleft()
1000000 loops, best of 3: 1.46 µs per loop

%timeit d = deque(string.letters)
1000000 loops, best of 3: 1.4 µs per loop

%timeit l = list(string.letters); l.pop(0)
1000000 loops, best of 3: 1.47 µs per loop

%timeit l = list(string.letters);
1000000 loops, best of 3: 1.22 µs per loop

d = deque(range(100000000))

%timeit d.popleft()
10000000 loops, best of 3: 90.5 ns per loop

l = range(100000000)

%timeit l.pop(0)
10 loops, best of 3: 93.4 ms per loop
2 of 3
28

Is there performance difference?

Yes. deque.popleft() is O(1) -- a constant time operation. While list.pop(0) is O(n) -- linear time operation: the larger the list the longer it takes.

Why?

CPython list implementation is array-based. pop(0) removes the first item from the list and it requires to shift left len(lst) - 1 items to fill the gap.

deque() implementation uses a doubly linked list. No matter how large the deque, deque.popleft() requires a constant (limited above) number of operations.

🌐
Codecademy
codecademy.com › docs › python › deque › .popleft()
Python | Deque | .popleft() | Codecademy
October 23, 2025 - A deque (double-ended queue) allows elements to be added or removed efficiently from both ends. Calling .popleft() on an empty deque raises an IndexError. ... Learn the basics of Python 3.12, one of the most powerful, versatile, and in-demand ...
🌐
Pythontic
pythontic.com › containers › deque › popleft
The popleft() method of deque class | Pythontic.com
A deque Python is double ended queue. Elements can be added and removed from either side of the deque. The popleft() method removes an element from the left side of the deque and returns the element.
🌐
Real Python
realpython.com › python-deque
Python's deque: Implement Efficient Queues and Stacks – Real Python
January 12, 2026 - To enqueue a person, you use .append(), which adds individual items to the right end. To dequeue a person, you use .popleft(), which removes and returns the item at the left end of a deque.
Find elsewhere
🌐
Reddit
reddit.com › r/learnpython › popleft() issues...
r/learnpython on Reddit: popleft() issues...
July 2, 2019 -

Having issues with using the popleft() function.

Let's say I have:

trees = [t1, t2, t3, t4]
t1 = ["oak", 1963, "NW corner"]
t2 = ["pine", 1975, "NE corner"]
t3 = ["elm", 1982, "SW corner"]
t4 = ["maple", 1992, "SE corner"]

If I issue the command trees.popleft(), I get the following error:

Traceback (most recent call last):
  File "<pyshell#24>", line 1, in <module>
    trees.popleft()
AttributeError: 'list' object has no attribute 'popleft'

Am I doing something wrong?

I'm just getting started in Python... I haven't gotten to the part where I have learned how to decipher error messages yet.

I'm using Python 3.7.3 on a Windows machine if that makes any difference.

🌐
Dataquest
dataquest.io › blog › python-deque-queues-stacks
Python Deque Function: A Better Choice for Queues and Stacks – Dataquest
April 7, 2025 - This function won't actually play a song since the goal is just to make a representation of queue functioning in Python. Instead, this function takes in a queue, deletes the leftmost element, and prints the deleted item and the current queue.
🌐
Medium
medium.com › @mollihua › pop-first-element-of-a-queue-in-python-list-pop-0-vs-collections-deque-popleft-7991408e45b
Pop first element of a queue in Python — list.pop(0) vs deque.popleft() | by mollihua | Medium
July 2, 2020 - def listpop(alist): ts = time.time() alist.pop(0) te = time.time() print("{:e}".format(te - ts))def dequepopleft(alist): q = collections.deque(alist) ts = time.time() q.popleft() te = time.time() print("{:e} seconds".format(te - ts))a = [x for x in range(10**6)]listpop(a) # output: 4.558802e-03 seconds dequepopleft(a) # output: 2.861023e-06 seconds · Python ·
🌐
TutorialsPoint
tutorialspoint.com › deque-in-python
Deque in Python
June 26, 2020 - import collections as col #Insert some elements into the queue at first my_deque = col.deque('124dfre') print('Dequeue: ' + str(my_deque)) #delete item from right and left item = my_deque.pop() print('Popped Item: ' + str(item)) item = my_deque.popleft() print('Popped Item: ' + str(item)) print('Dequeue after pop operations: ' + str(my_deque)) Dequeue: deque(['1', '2', '4', 'd', 'f', 'r', 'e']) Popped Item: e Popped Item: 1 Dequeue after pop operations: deque(['2', '4', 'd', 'f', 'r']) Some functions in Deque are used to get information related to items.
🌐
Python.org
discuss.python.org › ideas
Deque.append() should return popped item - Ideas - Discussions on Python.org
November 19, 2024 - If a deque is used with a fixed size, appending to one end will pop from the other end. However, there’s currently no way to reference this popped item. If I want to use it as a FIFO, I need to make sure that I pop from the right direction ...
🌐
Medium
medium.com › analytics-vidhya › a-brief-overview-of-queue-in-python-7e9ea57a47e4
A brief overview of Queue in Python | by Nilson Chapagain | Analytics Vidhya | Medium
August 8, 2021 - popleft( ) :- delete the value from the left end of deque. Deque is preferred over the list in the cases where we need quicker append and pop operations from both the ends of the container, as deque provides an O(1) time complexity for append ...
Top answer
1 of 3
4

Well, first off, it's called pop for both list and deque, there is no popright method on deques.

There is usually no meaningful performance difference between the two; every once in a while, a pop on a deque will cause a block deallocation (which has fixed overhead, it just makes that particular pop a little more costly), and on a list it can cause a realloc to shrink the underlying storage (which could end up being O(n), but only a tiny fraction of pops will cause it); asymptotically they're both O(1) operations. If your list is truly huge, then shrinks a lot you might get the occasional performance hiccup when it shrinks the underlying storage, but otherwise you're highly unlikely to notice a difference.

In answer to your question, deques are ever-so-slightly more efficient for use as stacks than lists; if you're importing collections anyway, and need a stack based structure, using a deque will get you a tiny benefit (at least on CPython, can't speak to other implementation). But it's not really worth micro-optimizing here; the cost of importing collections in the first place, and the cost of whatever useful code you execute based on this stack, likely dwarfs whatever tiny difference you'll see between list and deque for pops from the right. A simple ipython3 microbenchmark:

In [24]: %%timeit from collections import deque; s = deque([0] * 10000); onethousandnones = (None,) * 1000; pop = s.pop
    ...: ; push = s.append
    ...: for _ in onethousandnones:
    ...:     pop()
    ...: for _ in onethousandnones:
    ...:     push(0)
    ...:
    ...:
104 µs ± 7.99 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [25]: %%timeit s = [0] * 10000; onethousandnones = (None,) * 1000; pop = s.pop; push = s.append
    ...: for _ in onethousandnones:
    ...:     pop()
    ...: for _ in onethousandnones:
    ...:     push(0)
    ...:
    ...:
131 µs ± 8.93 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

So for a 1000 pops followed by 1000 pushes onto our stack, the deque-based stack took 30 µs less (~15 ns less per operation). Now admittedly, if I remove the call parentheses to time the base overhead, the base overhead was around 50 µs, so the overhead specifically attributable to the list is a significant fraction of the "minimum cost" of the deque, but it's still pretty small in the context of a program that is presumably doing something useful, not just pushing and popping to a stack. And it's pretty stable regardless of size; for a stack that's 10x the size, the cost remains unchanged for both deque and list. If the stack was growing and shrinking so much that list's amortized growth was kicking in, it might suffer a little more from the larger reallocations, but it's not normally something to worry about.

2 of 3
2

list.pop() is O(1). It doesn't need to copy anything, it just clears the last element and decrements the length of the list.

Deques are designed to optimize pushing and popping from either end, so both popleft() and popright() are O(1).

🌐
Note.nkmk.me
note.nkmk.me › home › python
How to Use Deque in Python: collections.deque | note.nkmk.me
April 20, 2025 - To use deque as a queue, add elements with append() and remove them with popleft().
🌐
Python Module of the Week
pymotw.com › 2 › collections › deque.html
Deque - Python Module of the Week
Use pop() to remove an item from the “right” end of the deque and popleft() to take from the “left” end. $ python collections_deque_consuming.py From the right: g f e d c b a From the left: a b c d e f g
🌐
Medium
medium.com › @codingcampus › deque-in-python-34a02ad0e498
Deque in Python. A Deque is a data structure in the… | by CodingCampus | Medium
November 23, 2023 - With the popleft() function we removed the first object. Deques also allow you to access a value in your deque and return the first occurrence of that value with the index() function.