Estruturas de Dados em Python: Guia Completo

Aprenda sobre listas, tuplas, dicionários e conjuntos em Python. Operações, performance e quando usar cada estrutura com exemplos práticos de código.

7 min de leitura Equipe Python Brasil

Dominar as estruturas de dados nativas do Python é essencial para escrever código eficiente e elegante. Neste guia, você vai aprender tudo sobre as quatro estruturas fundamentais — listas, tuplas, dicionários e conjuntos — com exemplos práticos e dicas de performance.

Listas

Listas são a estrutura de dados mais versátil do Python. Elas são ordenadas, mutáveis e permitem elementos duplicados.

Criando listas

# Criando listas de diferentes formas
frutas = ["maçã", "banana", "laranja", "uva"]
numeros = [1, 2, 3, 4, 5]
misturada = [1, "texto", 3.14, True, None]
vazia = []

# Usando o construtor list()
letras = list("Python")  # ['P', 'y', 't', 'h', 'o', 'n']

# List comprehension
quadrados = [x ** 2 for x in range(10)]
print(quadrados)  # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Operações com listas

frutas = ["maçã", "banana", "laranja"]

# Adicionar elementos
frutas.append("uva")              # Adiciona no final
frutas.insert(1, "morango")       # Adiciona na posição 1
frutas.extend(["kiwi", "manga"])  # Adiciona múltiplos elementos

print(frutas)
# ['maçã', 'morango', 'banana', 'laranja', 'uva', 'kiwi', 'manga']

# Remover elementos
frutas.remove("banana")    # Remove pela valor
ultimo = frutas.pop()      # Remove e retorna o último
primeiro = frutas.pop(0)   # Remove e retorna pela posição

# Buscar e contar
indice = frutas.index("laranja")  # Retorna o índice
quantidade = frutas.count("uva")  # Conta ocorrências
existe = "kiwi" in frutas          # Verifica se existe (True/False)

Fatiamento (Slicing)

numeros = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# lista[início:fim:passo]
print(numeros[2:5])     # [2, 3, 4]
print(numeros[:3])      # [0, 1, 2]
print(numeros[7:])      # [7, 8, 9]
print(numeros[::2])     # [0, 2, 4, 6, 8] (passo 2)
print(numeros[::-1])    # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] (invertido)

# Copiar uma lista (cópia superficial)
copia = numeros[:]
# ou
copia = numeros.copy()

Ordenação

notas = [8.5, 9.2, 7.0, 6.8, 9.8, 7.5]

# Ordenar in-place (modifica a lista original)
notas.sort()
print(notas)  # [6.8, 7.0, 7.5, 8.5, 9.2, 9.8]

notas.sort(reverse=True)
print(notas)  # [9.8, 9.2, 8.5, 7.5, 7.0, 6.8]

# Ordenar sem modificar (retorna nova lista)
alunos = [
    {"nome": "Ana", "nota": 8.5},
    {"nome": "Carlos", "nota": 9.2},
    {"nome": "Beatriz", "nota": 7.8},
]

ranking = sorted(alunos, key=lambda a: a["nota"], reverse=True)
for i, aluno in enumerate(ranking, 1):
    print(f"{i}º lugar: {aluno['nome']} - Nota: {aluno['nota']}")

List Comprehensions avançadas

# Filtrar e transformar
numeros = range(1, 21)

# Números pares elevados ao cubo
pares_cubo = [n ** 3 for n in numeros if n % 2 == 0]
print(pares_cubo)  # [8, 64, 216, 512, 1000, ...]

# Comprehension com condição ternária
classificacao = ["par" if n % 2 == 0 else "ímpar" for n in range(1, 6)]
print(classificacao)  # ['ímpar', 'par', 'ímpar', 'par', 'ímpar']

# Comprehension aninhada (achatar matriz)
matriz = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
achatada = [num for linha in matriz for num in linha]
print(achatada)  # [1, 2, 3, 4, 5, 6, 7, 8, 9]

Tuplas

Tuplas são parecidas com listas, mas são imutáveis — uma vez criadas, não podem ser alteradas. Isso as torna mais seguras e um pouco mais rápidas.

# Criando tuplas
coordenadas = (23.5505, -46.6333)  # São Paulo
cores_rgb = (255, 128, 0)
singleton = (42,)  # Tupla com um elemento (vírgula obrigatória!)

# Desempacotamento
latitude, longitude = coordenadas
print(f"Latitude: {latitude}, Longitude: {longitude}")

# Desempacotamento com *
primeiro, *meio, ultimo = (1, 2, 3, 4, 5)
print(primeiro)  # 1
print(meio)      # [2, 3, 4]
print(ultimo)    # 5

Quando usar tuplas em vez de listas?

# 1. Dados que não devem mudar
MESES = ("Janeiro", "Fevereiro", "Março", "Abril", "Maio",
         "Junho", "Julho", "Agosto", "Setembro", "Outubro",
         "Novembro", "Dezembro")

# 2. Como chaves de dicionário (listas não podem ser chaves)
localizacoes = {
    (-23.55, -46.63): "São Paulo",
    (-22.90, -43.17): "Rio de Janeiro",
    (-15.78, -47.93): "Brasília",
}

# 3. Retornar múltiplos valores de uma função
def dividir(a, b):
    quociente = a // b
    resto = a % b
    return quociente, resto  # Retorna uma tupla

q, r = dividir(17, 5)
print(f"17 ÷ 5 = {q} com resto {r}")

# Named tuples para maior clareza
from collections import namedtuple

Ponto = namedtuple("Ponto", ["x", "y"])
p = Ponto(3, 4)
print(f"Ponto({p.x}, {p.y})")
print(f"Distância da origem: {(p.x**2 + p.y**2)**0.5:.2f}")

Dicionários

Dicionários armazenam pares chave-valor. São incrivelmente rápidos para buscar dados e são uma das estruturas mais utilizadas no dia a dia.

# Criando dicionários
aluno = {
    "nome": "Maria Silva",
    "idade": 22,
    "curso": "Ciência da Computação",
    "notas": [8.5, 9.0, 7.5, 8.8],
    "ativo": True,
}

# Acessando valores
print(aluno["nome"])              # Maria Silva
print(aluno.get("email", "N/A")) # N/A (valor padrão se não existir)

# Modificando
aluno["idade"] = 23
aluno["email"] = "maria@email.com"

# Removendo
del aluno["ativo"]
curso = aluno.pop("curso")  # Remove e retorna o valor

Iteração em dicionários

estoque = {
    "notebook": {"preco": 3500, "quantidade": 25},
    "mouse": {"preco": 89.90, "quantidade": 150},
    "teclado": {"preco": 199.90, "quantidade": 80},
    "monitor": {"preco": 1200, "quantidade": 40},
}

# Iterar pelas chaves
for produto in estoque:
    print(produto)

# Iterar pelos valores
for info in estoque.values():
    print(info)

# Iterar pelos pares chave-valor
for produto, info in estoque.items():
    valor_total = info["preco"] * info["quantidade"]
    print(f"{produto}: R${valor_total:,.2f} em estoque")

# Dict comprehension
precos = {produto: info["preco"] for produto, info in estoque.items()}
print(precos)
# {'notebook': 3500, 'mouse': 89.9, 'teclado': 199.9, 'monitor': 1200}

# Filtrar por condição
caros = {p: i for p, i in estoque.items() if i["preco"] > 100}

Métodos úteis de dicionários

config_padrao = {
    "tema": "claro",
    "idioma": "pt-BR",
    "notificacoes": True,
    "fonte_tamanho": 14,
}

config_usuario = {
    "tema": "escuro",
    "fonte_tamanho": 16,
}

# Mesclar dicionários
config_final = {**config_padrao, **config_usuario}
print(config_final)
# {'tema': 'escuro', 'idioma': 'pt-BR', 'notificacoes': True, 'fonte_tamanho': 16}

# Python 3.9+: operador merge
config_final = config_padrao | config_usuario

# defaultdict para contagem
from collections import defaultdict, Counter

texto = "banana abacaxi banana maçã laranja banana maçã"
palavras = texto.split()

# Usando Counter
contagem = Counter(palavras)
print(contagem.most_common(3))
# [('banana', 3), ('maçã', 2), ('abacaxi', 1)]

Conjuntos (Sets)

Conjuntos são coleções não ordenadas de elementos únicos. Eles são ótimos para eliminar duplicatas e fazer operações matemáticas de conjuntos.

# Criando conjuntos
frutas = {"maçã", "banana", "laranja", "maçã"}  # duplicata ignorada
print(frutas)  # {'banana', 'laranja', 'maçã'}

numeros = set([1, 2, 2, 3, 3, 3, 4, 4, 4, 4])
print(numeros)  # {1, 2, 3, 4}

# Adicionar e remover
frutas.add("uva")
frutas.discard("banana")  # Não dá erro se não existir

Operações de conjuntos

python_devs = {"Ana", "Carlos", "Maria", "João", "Pedro"}
javascript_devs = {"Carlos", "Maria", "Lucas", "Fernanda", "Pedro"}

# União: quem sabe pelo menos uma
todos = python_devs | javascript_devs
# ou: python_devs.union(javascript_devs)
print(f"Total de devs: {len(todos)}")

# Interseção: quem sabe as duas
fullstack = python_devs & javascript_devs
print(f"Fullstack: {fullstack}")  # {'Carlos', 'Maria', 'Pedro'}

# Diferença: quem sabe só Python
so_python = python_devs - javascript_devs
print(f"Só Python: {so_python}")  # {'Ana', 'João'}

# Diferença simétrica: quem sabe só uma
exclusivos = python_devs ^ javascript_devs
print(f"Exclusivos: {exclusivos}")  # {'Ana', 'João', 'Lucas', 'Fernanda'}

Uso prático: eliminando duplicatas

# Remover duplicatas mantendo a ordem
def remover_duplicatas(lista):
    vistos = set()
    resultado = []
    for item in lista:
        if item not in vistos:
            vistos.add(item)
            resultado.append(item)
    return resultado

emails = [
    "ana@email.com",
    "carlos@email.com",
    "ana@email.com",
    "maria@email.com",
    "carlos@email.com",
]

unicos = remover_duplicatas(emails)
print(unicos)  # ['ana@email.com', 'carlos@email.com', 'maria@email.com']

Comparação de Performance

A escolha da estrutura de dados impacta diretamente a performance do seu código:

OperaçãoListaTuplaDicionárioConjunto
Acesso por índiceO(1)O(1)
Busca por valorO(n)O(n)O(1)O(1)
InserçãoO(1)*O(1)O(1)
RemoçãoO(n)O(1)O(1)
MemóriaMédiaBaixaAltaMédia

*O(1) para append; O(n) para insert no início.

import time

# Demonstrando a diferença de busca
tamanho = 1_000_000

lista_grande = list(range(tamanho))
conjunto_grande = set(range(tamanho))

# Busca na lista: O(n) - lento
inicio = time.time()
999_999 in lista_grande
tempo_lista = time.time() - inicio

# Busca no conjunto: O(1) - rápido
inicio = time.time()
999_999 in conjunto_grande
tempo_set = time.time() - inicio

print(f"Lista: {tempo_lista:.6f}s")
print(f"Conjunto: {tempo_set:.6f}s")
print(f"Conjunto é {tempo_lista/tempo_set:.0f}x mais rápido!")

Resumo: Quando Usar Cada Uma?

  • Lista: Quando precisa de uma coleção ordenada e mutável. Ideal para sequências de dados que podem ser modificados.
  • Tupla: Quando os dados não devem mudar. Ideal para coordenadas, retorno de funções, chaves de dicionário.
  • Dicionário: Quando precisa associar chaves a valores. Ideal para configurações, mapeamentos, dados estruturados.
  • Conjunto: Quando precisa de elementos únicos ou fazer operações de conjuntos. Ideal para eliminar duplicatas e verificar pertinência.

Dominar essas quatro estruturas é fundamental para se tornar um bom programador Python. Pratique com projetos reais e você vai perceber que escolher a estrutura certa faz toda a diferença no seu código!

E

Equipe Python Brasil

Contribuidor do Python Brasil — Aprenda Python em Português