How to peek front of deque without popping?
Question:
I want to check a condition against the front of a queue before deciding whether or not to pop. How can I achieve this in python with collections.deque?
list(my_deque)[0]
seems ugly and poor for performance.
Answers:
TL;DR: assuming your deque
is called d
, just inspect d[0]
, since the "leftmost" element in a deque is the front (you might want to test before the length of the deque to make sure it’s not empty). Taking @asongtoruin’s suggestion, use if d:
to test whether the deque is empty (it’s equivalent to if len(d) == 0:
, but more pythonic)
###Why not converting to list?
Because deque
s are indexable and you’re testing the front. While a deque
has an interface similar to a list, the implementation is optimized for front- and back- operations. Quoting the documentation:
Deques support thread-safe, memory efficient appends and pops from
either side of the deque with approximately the same O(1) performance
in either direction.
Though list objects support similar operations, they are optimized for
fast fixed-length operations and incur O(n) memory movement costs for
pop(0) and insert(0, v) operations which change both the size and
position of the underlying data representation.
Converting to list might be desirable if you have lots of operations accessing the "middle" of the queue. Again quoting the documentation:
Indexed access is O(1) at both ends but slows to O(n) in the middle.
For fast random access, use lists instead.
Conversion to list
is O(n), but every subsequent access is O(1).
You can simply find the last element using my_deque[-1]
or my_deque[len(my_deque)-1]
.
Here is a simple implementation that allowed me to check the front of the queue before popping (using while
and q[0]
):
Apply your own condition against q[0]
, before q.popleft()
, below:
testLst = [100,200,-100,400,340]
q=deque(testLst)
while q:
print(q)
print('{}{}'.format("length of queue: ", len(q)))
print('{}{}'.format("head: ", q[0]))
print()
q.popleft()
output:
deque([100, 200, -100, 400, 340])
length of queue: 5
head: 100
deque([200, -100, 400, 340])
length of queue: 4
head: 200
deque([-100, 400, 340])
length of queue: 3
head: -100
deque([400, 340])
length of queue: 2
head: 400
deque([340])
length of queue: 1
head: 340
Assuming your deque is implemented from collections python
from collections import deque
deque = deque() //syntax
Deque too can be interpreted as a list in terms of accessing using indices.
You can peek front element by using deque[0]
and peek last using deque[-1]
This works without popping elements from left or right and seems efficient too.
I want to check a condition against the front of a queue before deciding whether or not to pop. How can I achieve this in python with collections.deque?
list(my_deque)[0]
seems ugly and poor for performance.
TL;DR: assuming your deque
is called d
, just inspect d[0]
, since the "leftmost" element in a deque is the front (you might want to test before the length of the deque to make sure it’s not empty). Taking @asongtoruin’s suggestion, use if d:
to test whether the deque is empty (it’s equivalent to if len(d) == 0:
, but more pythonic)
###Why not converting to list?
Because deque
s are indexable and you’re testing the front. While a deque
has an interface similar to a list, the implementation is optimized for front- and back- operations. Quoting the documentation:
Deques support thread-safe, memory efficient appends and pops from
either side of the deque with approximately the same O(1) performance
in either direction.Though list objects support similar operations, they are optimized for
fast fixed-length operations and incur O(n) memory movement costs for
pop(0) and insert(0, v) operations which change both the size and
position of the underlying data representation.
Converting to list might be desirable if you have lots of operations accessing the "middle" of the queue. Again quoting the documentation:
Indexed access is O(1) at both ends but slows to O(n) in the middle.
For fast random access, use lists instead.
Conversion to list
is O(n), but every subsequent access is O(1).
You can simply find the last element using my_deque[-1]
or my_deque[len(my_deque)-1]
.
Here is a simple implementation that allowed me to check the front of the queue before popping (using while
and q[0]
):
Apply your own condition against q[0]
, before q.popleft()
, below:
testLst = [100,200,-100,400,340]
q=deque(testLst)
while q:
print(q)
print('{}{}'.format("length of queue: ", len(q)))
print('{}{}'.format("head: ", q[0]))
print()
q.popleft()
output:
deque([100, 200, -100, 400, 340])
length of queue: 5
head: 100
deque([200, -100, 400, 340])
length of queue: 4
head: 200
deque([-100, 400, 340])
length of queue: 3
head: -100
deque([400, 340])
length of queue: 2
head: 400
deque([340])
length of queue: 1
head: 340
Assuming your deque is implemented from collections python
from collections import deque
deque = deque() //syntax
Deque too can be interpreted as a list in terms of accessing using indices.
You can peek front element by using deque[0]
and peek last using deque[-1]
This works without popping elements from left or right and seems efficient too.