Course topics

By WebNest Studio

Python Tutorial

Arrays, Stacks and Queues in Python

Classic data structures appear constantly in real programs and coding interviews: arrays of numbers, stacks (last in, first out) for undo and expression parsing, and queues (first in, first out) for task processing and breadth-first search. Python has no separate "array" keyword, but it gives you efficient tools for all of them.

This lesson covers the array module, implementing stacks with lists, queues with collections.deque, priority queues with heapq, and the thread-safe queue module.

The array Module

array.array(typecode, items) stores numbers of one type compactly, like arrays in C — for example 'i' for signed ints and 'd' for doubles. It uses much less memory than a list of Python ints. For numerical computing, NumPy arrays (see the NumPy lesson) are the more powerful choice.

Stacks (LIFO)

A list is a perfect stack: append() pushes and pop() pops from the end, both O(1). Stacks power undo history, browser back buttons, matching brackets and depth-first search.

Queues (FIFO)

Do not use list.pop(0) for queues — it is O(n) because every item shifts. collections.deque supports O(1) append and popleft at both ends, and a maxlen for bounded buffers.

Priority Queues and Thread-Safe Queues

heapq turns a list into a min-heap: heappush and heappop always return the smallest item in O(log n) — ideal for scheduling by priority and Dijkstra's algorithm. queue.Queue, LifoQueue and PriorityQueue add locking for producer/consumer threads.

Examples

The array module

Python
from array import array
import sys

temps = array("d", [21.5, 23.0, 19.8])
temps.append(25.1)
temps.extend([18.0, 22.4])
print(temps, temps[1], len(temps))
print(max(temps), round(sum(temps) / len(temps), 2))

ints = array("h", range(1000))                # "h" = 2-byte signed integers
print(sys.getsizeof(ints) < sys.getsizeof(list(range(1000))))
try:
    ints.append(3.5)
except TypeError as e:
    print("TypeError:", e)
Output
array('d', [21.5, 23.0, 19.8, 25.1, 18.0, 22.4]) 23.0 6
25.1 21.63
True
TypeError: 'float' object cannot be interpreted as an integer

Stack: checking balanced brackets

Python
def balanced(expression):
    pairs = {")": "(", "]": "[", "}": "{"}
    stack = []
    for ch in expression:
        if ch in "([{":
            stack.append(ch)                 # push
        elif ch in pairs:
            if not stack or stack.pop() != pairs[ch]:   # pop
                return False
    return not stack

for e in ["(a + b) * [c]", "{[()]}", "(]", "((x)"]:
    print(e, "->", balanced(e))
Output
(a + b) * [c] -> True
{[()]} -> True
(] -> False
((x) -> False

Queue with deque, and a bounded recent-items buffer

Python
from collections import deque

tasks = deque(["email", "report", "backup"])
tasks.append("cleanup")
print("processing", tasks.popleft())
print("processing", tasks.popleft())
print("remaining", list(tasks))

recent = deque(maxlen=3)
for page in ["home", "courses", "python", "fastapi", "pricing"]:
    recent.append(page)
print("last 3 pages:", list(recent))
recent.rotate(1)
print(list(recent))
Output
processing email
processing report
remaining ['backup', 'cleanup']
last 3 pages: ['python', 'fastapi', 'pricing']
['pricing', 'python', 'fastapi']

Priority queue with heapq

Python
import heapq

tickets = []
heapq.heappush(tickets, (3, "Change avatar"))
heapq.heappush(tickets, (1, "Payment failed"))
heapq.heappush(tickets, (2, "Cannot log in"))
while tickets:
    priority, title = heapq.heappop(tickets)
    print(priority, title)

print(heapq.nlargest(2, [40, 10, 90, 70]), heapq.nsmallest(2, [40, 10, 90, 70]))
Output
1 Payment failed
2 Cannot log in
3 Change avatar
[90, 70] [10, 40]

Common Mistakes

  • Using list.pop(0) or insert(0, x) for queues — O(n); use deque.
  • Expecting heapq to be a max-heap — it is a min-heap; negate priorities for max.
  • Mixing types in array.array, which only accepts its declared type.
  • Using plain lists shared between threads instead of queue.Queue.

Key Points to Remember

  • array.array stores same-typed numbers compactly.
  • Lists are efficient stacks with append/pop.
  • collections.deque is the right queue: O(1) append/popleft, optional maxlen.
  • heapq provides priority queues (min-heap).
  • queue.Queue is thread-safe for producer/consumer code.

Practice the examples

Change an input, predict the result, then compare it with the output. Explain why the result changes.