Skip to main content

How to Get the First and Last Elements of a Deque in Python

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: 50

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}") # Unchanged

Output:

Deque: deque(['apple', 'banana', 'cherry', 'date', 'elderberry'])
First element: apple
Last element: elderberry
Deque after: deque(['apple', 'banana', 'cherry', 'date', 'elderberry'])
tip

This is the preferred method when you simply want to peek at the first or last element without removing it. It's an O(1) operation, making it very efficient.

caution

Accessing by index on an empty deque raises an IndexError:

from collections import deque

empty_dq = deque()
print(empty_dq[0]) # IndexError: deque index out of range

Always check if the deque is non-empty before accessing:

if dq:
print(dq[0])
else:
print("Deque is empty")

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 removed

Output:

Before: deque([10, 20, 30, 40, 50])
First: 10
Last: 50
After: deque([20, 30, 40])
caution

popleft() and pop() remove the elements from the deque. Only use them when you intend to consume the data, such as when processing items from a queue.

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])

# Unpack first and last (only works for 2+ elements)
first, *middle, last = dq
print(f"First: {first}, Last: {last}")

Output:

First: 10, Last: 50
caution

This approach creates intermediate lists and only works when the deque has at least 2 elements. A single-element deque will raise a ValueError. Use indexing ([0] and [-1]) for the general case.

Comparison of Methods

MethodReturnsModifies DequeEmpty DequeTime Complexity
dq[0] / dq[-1]Element value❌ NoRaises IndexErrorO(1)
dq.popleft() / dq.pop()Element value✅ Yes (removes)Raises IndexErrorO(1)
first, *_, last = dqBoth values❌ NoRaises ValueErrorO(n)

Practical Examples

Using a Deque as a Queue (FIFO)

from collections import deque

# Task queue
tasks = deque(['task_1', 'task_2', 'task_3', 'task_4'])

# Peek at the next task without removing it
print(f"Next task: {tasks[0]}")

# Process the next task (removes it)
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

# Fixed-size sliding window of last 3 values
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: 50

Safe 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

# Non-empty deque
dq = deque([10, 20, 30])
print(f"First: {peek_first(dq)}")
print(f"Last: {peek_last(dq)}")

# Empty deque
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/A

Conclusion

  • To get the first and last elements of a deque in Python, use index access with dq[0] and dq[-1]. This is the simplest, fastest (O(1)), and safest approach because it does not modify the deque.
  • Use popleft() and pop() 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.