---
title: "Pilhas e Filas em Python: Implementacao com Listas e deque"
url: "https://python.dev.br/algoritmos/pilhas-filas-python/"
markdown_url: "https://python.dev.br/algoritmos/pilhas-filas-python.MD"
description: "Aprenda pilhas (stack) e filas (queue) em Python com listas, deque e heapq. Implementacoes praticas, priority queue e casos de uso reais como BFS e undo."
date: "2026-04-27"
author: "Equipe Python Brasil"
---

# Pilhas e Filas em Python: Implementacao com Listas e deque

Aprenda pilhas (stack) e filas (queue) em Python com listas, deque e heapq. Implementacoes praticas, priority queue e casos de uso reais como BFS e undo.


## Pilhas e Filas: Estruturas Fundamentais

Pilhas (stacks) e filas (queues) sao duas das estruturas de dados mais importantes da computacao. Elas controlam a **ordem** em que elementos sao processados e aparecem em inumeros cenarios reais: desde o "Desfazer" do seu editor de texto ate o agendamento de tarefas em servidores.

Em Python, podemos implementa-las com [listas](/algoritmos/listas-python/), `collections.deque` e modulos especializados como `heapq` e `queue`. Vamos explorar cada abordagem.

---

## Pilha (Stack) — LIFO

Uma pilha segue o principio **LIFO** (Last In, First Out): o ultimo elemento adicionado e o primeiro a ser removido. Pense numa pilha de pratos — voce sempre pega o prato do topo.

### Operacoes Principais

| Operacao | Descricao | Complexidade |
|---|---|---|
| push | Adicionar ao topo | O(1) |
| pop | Remover do topo | O(1) |
| peek/top | Ver o topo sem remover | O(1) |
| is_empty | Verificar se esta vazia | O(1) |

### Implementacao com Lista

```python
class Pilha:
    def __init__(self):
        self._dados = []

    def push(self, item):
        """Adiciona item ao topo da pilha."""
        self._dados.append(item)

    def pop(self):
        """Remove e retorna o item do topo."""
        if self.esta_vazia():
            raise IndexError("Pilha vazia")
        return self._dados.pop()

    def topo(self):
        """Retorna o item do topo sem remover."""
        if self.esta_vazia():
            raise IndexError("Pilha vazia")
        return self._dados[-1]

    def esta_vazia(self):
        return len(self._dados) == 0

    def tamanho(self):
        return len(self._dados)

    def __repr__(self):
        return f"Pilha({self._dados})"

# Uso
pilha = Pilha()
pilha.push(10)
pilha.push(20)
pilha.push(30)
print(pilha.topo())  # 30
print(pilha.pop())   # 30
print(pilha.pop())   # 20
print(pilha)         # Pilha([10])
```

### Implementacao com deque

```python
from collections import deque

class PilhaDeque:
    def __init__(self):
        self._dados = deque()

    def push(self, item):
        self._dados.append(item)

    def pop(self):
        if not self._dados:
            raise IndexError("Pilha vazia")
        return self._dados.pop()

    def topo(self):
        if not self._dados:
            raise IndexError("Pilha vazia")
        return self._dados[-1]

    def esta_vazia(self):
        return len(self._dados) == 0
```

### Caso de Uso: Sistema de Undo/Redo

```python
class EditorTexto:
    def __init__(self):
        self.texto = ""
        self._undo_stack = []
        self._redo_stack = []

    def digitar(self, novo_texto):
        self._undo_stack.append(self.texto)
        self._redo_stack.clear()
        self.texto += novo_texto

    def desfazer(self):
        if not self._undo_stack:
            print("Nada para desfazer")
            return
        self._redo_stack.append(self.texto)
        self.texto = self._undo_stack.pop()

    def refazer(self):
        if not self._redo_stack:
            print("Nada para refazer")
            return
        self._undo_stack.append(self.texto)
        self.texto = self._redo_stack.pop()

# Uso
editor = EditorTexto()
editor.digitar("Ola ")
editor.digitar("mundo ")
editor.digitar("Python!")
print(editor.texto)     # "Ola mundo Python!"

editor.desfazer()
print(editor.texto)     # "Ola mundo "

editor.desfazer()
print(editor.texto)     # "Ola "

editor.refazer()
print(editor.texto)     # "Ola mundo "
```

### Caso de Uso: Verificar Parenteses Balanceados

```python
def parenteses_balanceados(expressao):
    """Verifica se parenteses, colchetes e chaves estao balanceados."""
    pilha = []
    pares = {")": "(", "]": "[", "}": "{"}

    for char in expressao:
        if char in "([{":
            pilha.append(char)
        elif char in ")]}":
            if not pilha or pilha[-1] != pares[char]:
                return False
            pilha.pop()

    return len(pilha) == 0

print(parenteses_balanceados("((a + b) * [c - d])"))  # True
print(parenteses_balanceados("((a + b)"))               # False
print(parenteses_balanceados("{[}]"))                    # False
```

Este e um problema classico de [entrevistas Python](/carreira/entrevistas-python/).

---

## Fila (Queue) — FIFO

Uma fila segue o principio **FIFO** (First In, First Out): o primeiro elemento adicionado e o primeiro a ser removido. Como uma fila de supermercado — quem chegou primeiro e atendido primeiro.

### Operacoes Principais

| Operacao | Descricao | Complexidade (deque) |
|---|---|---|
| enqueue | Adicionar ao final | O(1) |
| dequeue | Remover do inicio | O(1) |
| front | Ver o primeiro sem remover | O(1) |
| is_empty | Verificar se esta vazia | O(1) |

### Por que Nao Usar Lista para Filas

```python
# NAO FACA ISSO — pop(0) e O(n)!
fila_ruim = [1, 2, 3, 4, 5]
fila_ruim.pop(0)  # Remove o 1, mas desloca todos os outros elementos
```

Remover do inicio de uma [lista](/algoritmos/listas-python/) e O(n) porque todos os elementos precisam ser deslocados. Use `deque` que oferece O(1) em ambas as pontas.

### Implementacao com deque

```python
from collections import deque

class Fila:
    def __init__(self):
        self._dados = deque()

    def enfileirar(self, item):
        """Adiciona item ao final da fila."""
        self._dados.append(item)

    def desenfileirar(self):
        """Remove e retorna o primeiro item."""
        if self.esta_vazia():
            raise IndexError("Fila vazia")
        return self._dados.popleft()

    def primeiro(self):
        """Retorna o primeiro item sem remover."""
        if self.esta_vazia():
            raise IndexError("Fila vazia")
        return self._dados[0]

    def esta_vazia(self):
        return len(self._dados) == 0

    def tamanho(self):
        return len(self._dados)

    def __repr__(self):
        return f"Fila({list(self._dados)})"

# Uso
fila = Fila()
fila.enfileirar("Cliente 1")
fila.enfileirar("Cliente 2")
fila.enfileirar("Cliente 3")
print(fila.primeiro())       # "Cliente 1"
print(fila.desenfileirar())  # "Cliente 1"
print(fila.desenfileirar())  # "Cliente 2"
print(fila)                  # Fila(['Cliente 3'])
```

### Caso de Uso: BFS (Busca em Largura)

```python
from collections import deque

def bfs(grafo, inicio):
    """Busca em largura usando fila."""
    visitados = set()
    fila = deque([inicio])
    ordem = []

    while fila:
        vertice = fila.popleft()
        if vertice not in visitados:
            visitados.add(vertice)
            ordem.append(vertice)
            # Adicionar vizinhos nao visitados a fila
            for vizinho in grafo.get(vertice, []):
                if vizinho not in visitados:
                    fila.append(vizinho)

    return ordem

# Grafo de exemplo
grafo = {
    "A": ["B", "C"],
    "B": ["A", "D", "E"],
    "C": ["A", "F"],
    "D": ["B"],
    "E": ["B", "F"],
    "F": ["C", "E"]
}

print(bfs(grafo, "A"))
# ['A', 'B', 'C', 'D', 'E', 'F']
```

### Caso de Uso: Agendamento de Tarefas

```python
from collections import deque
from datetime import datetime

class AgendadorTarefas:
    def __init__(self):
        self._fila = deque()

    def adicionar_tarefa(self, nome, prioridade="normal"):
        tarefa = {
            "nome": nome,
            "prioridade": prioridade,
            "criada_em": datetime.now().isoformat()
        }
        if prioridade == "urgente":
            self._fila.appendleft(tarefa)  # Urgente vai para o inicio
        else:
            self._fila.append(tarefa)

    def processar_proxima(self):
        if not self._fila:
            return "Nenhuma tarefa pendente"
        tarefa = self._fila.popleft()
        return f"Processando: {tarefa['nome']} ({tarefa['prioridade']})"

    def pendentes(self):
        return len(self._fila)

# Uso
agendador = AgendadorTarefas()
agendador.adicionar_tarefa("Enviar relatorio")
agendador.adicionar_tarefa("Backup do banco")
agendador.adicionar_tarefa("Fix bug critico", "urgente")

print(agendador.processar_proxima())
# "Processando: Fix bug critico (urgente)"
```

Para processamento assincrono de tarefas em producao, veja nosso artigo sobre [Celery](/glossario/celery/) e [async/await em Python](/blog/python-async-await/).

---

## Fila de Prioridade com heapq

Uma fila de prioridade remove sempre o elemento com **menor prioridade** (menor valor). O modulo `heapq` implementa um min-heap eficiente:

```python
import heapq

class FilaPrioridade:
    def __init__(self):
        self._heap = []
        self._contador = 0  # Desempate para mesma prioridade

    def adicionar(self, item, prioridade):
        heapq.heappush(self._heap, (prioridade, self._contador, item))
        self._contador += 1

    def remover(self):
        if not self._heap:
            raise IndexError("Fila vazia")
        prioridade, _, item = heapq.heappop(self._heap)
        return item, prioridade

    def esta_vazia(self):
        return len(self._heap) == 0

# Uso — menor numero = maior prioridade
fila = FilaPrioridade()
fila.adicionar("Tarefa baixa prioridade", prioridade=3)
fila.adicionar("Tarefa critica", prioridade=1)
fila.adicionar("Tarefa media", prioridade=2)

while not fila.esta_vazia():
    item, prio = fila.remover()
    print(f"[P{prio}] {item}")
# [P1] Tarefa critica
# [P2] Tarefa media
# [P3] Tarefa baixa prioridade
```

### Operacoes do heapq

```python
import heapq

numeros = [5, 3, 8, 1, 9, 2]

# Transformar lista em heap — O(n)
heapq.heapify(numeros)
print(numeros)  # [1, 3, 2, 5, 9, 8]

# Inserir — O(log n)
heapq.heappush(numeros, 4)

# Remover o menor — O(log n)
menor = heapq.heappop(numeros)  # 1

# N menores/maiores — O(n log k)
dados = [15, 3, 28, 7, 42, 1, 19]
print(heapq.nsmallest(3, dados))  # [1, 3, 7]
print(heapq.nlargest(3, dados))   # [42, 28, 19]
```

---

## queue.Queue: Fila Thread-Safe

Para aplicacoes com [multiprocessing](/blog/python-multiprocessing/) ou threads, o modulo `queue` oferece filas seguras:

```python
from queue import Queue, LifoQueue, PriorityQueue
import threading

# Fila FIFO thread-safe
fila = Queue(maxsize=10)

def produtor(fila):
    for i in range(5):
        fila.put(f"Item {i}")
        print(f"Produzido: Item {i}")

def consumidor(fila):
    while True:
        item = fila.get()
        if item is None:
            break
        print(f"Consumido: {item}")
        fila.task_done()

# Iniciar threads
t_prod = threading.Thread(target=produtor, args=(fila,))
t_cons = threading.Thread(target=consumidor, args=(fila,))

t_prod.start()
t_cons.start()

t_prod.join()
fila.put(None)  # Sinal de parada
t_cons.join()
```

| Classe | Ordem | Uso |
|---|---|---|
| `Queue` | FIFO | Processamento em ordem |
| `LifoQueue` | LIFO (pilha) | Pilha thread-safe |
| `PriorityQueue` | Prioridade | Tarefas com prioridade |

---

## Comparacao: Quando Usar Cada Estrutura

| Estrutura | Ordem | Implementacao | Melhor Para |
|---|---|---|---|
| Pilha (lista) | LIFO | `list` | Undo, avaliacao de expressoes |
| Pilha (deque) | LIFO | `deque` | Thread-safe, alta performance |
| Fila (deque) | FIFO | `deque` | BFS, agendamento |
| Fila de prioridade | Prioridade | `heapq` | Dijkstra, agendamento com prioridade |
| Queue | FIFO thread-safe | `queue.Queue` | Produtor-consumidor com threads |

Para decidir entre essas e outras estruturas como [dicionarios](/algoritmos/dicionarios-python/) e sets, veja nosso guia de [estruturas de dados Python](/blog/estruturas-de-dados-python/).

---

## Conclusao

Pilhas e filas sao estruturas simples mas extremamente poderosas. Em Python, `collections.deque` e a ferramenta ideal para ambas — oferece O(1) em ambas as pontas e e mais eficiente que listas para filas. Para filas de prioridade, `heapq` e a escolha certa, e para cenarios com threads, use `queue.Queue`.

Domine essas estruturas e voce estara preparado para resolver problemas classicos de [entrevistas](/carreira/entrevistas-python/) e construir aplicacoes robustas.

Continue aprendendo: [listas](/algoritmos/listas-python/), [dicionarios](/algoritmos/dicionarios-python/), [ordenacao](/algoritmos/ordenacao-python/) e [busca binaria](/algoritmos/busca-binaria-python/).

<p>Veja como outras linguagens implementam essas estruturas: <a href="https://golang.com.br" target="_blank" rel="noopener" onclick="umami.track('portfolio-site-click', { destination: 'golang.com.br' })">Go</a>, <a href="https://rustlang.com.br" target="_blank" rel="noopener" onclick="umami.track('portfolio-site-click', { destination: 'rustlang.com.br' })">Rust</a> e <a href="https://kotlin.dev.br" target="_blank" rel="noopener" onclick="umami.track('portfolio-site-click', { destination: 'kotlin.dev.br' })">Kotlin</a>.</p>
