A deque (double-ended queue) from Python's collections module is a versatile data structure that allows efficient insertion and removal from both ends. Accessing the first and last elements is a common operation when using deques as queues, stacks, or sliding windows. In this guide, we'll show you multiple methods to retrieve these elements and explain when to use each approach.
Quick Answer
from collections import deque
dq = deque([10, 20, 30, 40, 50])
first = dq[0] # First element
last = dq[-1] # Last element
print(f"First: {first}, Last: {last}")Output:
First: 10, Last: 50Method 1: Using Index Access [0] and [-1] (Recommended)
The simplest and most common way to access the first and last elements is using square bracket indexing. This reads the values without modifying the deque:
from collections import deque
dq = deque(['apple', 'banana', 'cherry', 'date', 'elderberry'])
print(f"Deque: {dq}")
print(f"First element: {dq[0]}")
print(f"Last element: {dq[-1]}")
print(f"Deque after: {dq}") # UnchangedOutput:
Deque: deque(['apple', 'banana', 'cherry', 'date', 'elderberry'])
First element: apple
Last element: elderberry
Deque after: deque(['apple', 'banana', 'cherry', 'date', 'elderberry'])Method 2: Using popleft() and pop() (Removes Elements)
The popleft() method removes and returns the first element, while pop() removes and returns the last element:
from collections import deque
dq = deque([10, 20, 30, 40, 50])
print(f"Before: {dq}")
first = dq.popleft() # Removes and returns first element
last = dq.pop() # Removes and returns last element
print(f"First: {first}")
print(f"Last: {last}")
print(f"After: {dq}") # Elements are removedOutput:
Before: deque([10, 20, 30, 40, 50])
First: 10
Last: 50
After: deque([20, 30, 40])Handling empty deques:
from collections import deque
dq = deque()
try:
first = dq.popleft()
except IndexError:
print("Cannot pop from an empty deque")Method 3: Using Iteration (For Special Cases)
If you need both the first and last elements and want to handle edge cases gracefully, you can use unpacking:
from collections import deque
dq = deque([10, 20, 30, 40, 50])
first, *middle, last = dq
print(f"First: {first}, Last: {last}")Output:
First: 10, Last: 50Comparison of Methods
| Method | Returns | Modifies Deque | Empty Deque | Time Complexity |
|---|---|---|---|---|
dq[0] / dq[-1] |
Element value | ❌ No | Raises IndexError |
O(1) |
dq.popleft() / dq.pop() |
Element value | ✅ Yes (removes) | Raises IndexError |
O(1) |
first, *_, last = dq |
Both values | ❌ No | Raises ValueError |
O(n) |
Practical Examples
Using a Deque as a Queue (FIFO)
from collections import deque
tasks = deque(['task_1', 'task_2', 'task_3', 'task_4'])
print(f"Next task: {tasks[0]}")
current = tasks.popleft()
print(f"Processing: {current}")
print(f"Remaining: {tasks}")Output:
Next task: task_1
Processing: task_1
Remaining: deque(['task_2', 'task_3', 'task_4'])Using a Deque as a Sliding Window
from collections import deque
window = deque(maxlen=3)
for value in [10, 20, 30, 40, 50]:
window.append(value)
if len(window) == window.maxlen:
print(f"Window: {list(window)} | "
f"First: {window[0]}, Last: {window[-1]}")Output:
Window: [10, 20, 30] | First: 10, Last: 30
Window: [20, 30, 40] | First: 20, Last: 40
Window: [30, 40, 50] | First: 30, Last: 50Safe Access with a Helper Function
from collections import deque
def peek_first(dq, default=None):
"""Return the first element or a default if empty."""
return dq[0] if dq else default
def peek_last(dq, default=None):
"""Return the last element or a default if empty."""
return dq[-1] if dq else default
dq = deque([10, 20, 30])
print(f"First: {peek_first(dq)}")
print(f"Last: {peek_last(dq)}")
empty = deque()
print(f"First: {peek_first(empty, 'N/A')}")
print(f"Last: {peek_last(empty, 'N/A')}")Output:
First: 10
Last: 30
First: N/A
Last: N/AConclusion
- To get the first and last elements of a deque in Python, use index access with
dq[0]anddq[-1]. This is the simplest, fastest (O(1)), and safest approach because it does not modify the deque. - Use
popleft()andpop()only when you want to remove the elements while retrieving them (for example, when processing a queue). - Always check that the deque is non-empty before accessing elements to avoid
IndexError.