Python Admin

Guia Completo de Listas, Tuplas, Sets e Dicionários em Python na Prática Já leu

Estruturas de Dados em Python: Listas, Tuplas, Sets e Dicionários Python oferece quatro estruturas de dados fundamentais que você usará constantemente em seu dia a dia como programador. Cada uma delas foi projetada para resolver problemas específicos, e entender suas características, limitações e casos de uso é essencial para escrever código eficiente e legível. Neste artigo, vamos explorar cada uma dessas estruturas de forma prática, focando em aplicações reais que você encontrará em projetos profissionais. A escolha da estrutura correta não é apenas uma questão de estilo — ela impacta diretamente na performance, legibilidade e manutenibilidade do seu código. Uma decisão incorreta pode transformar um algoritmo linear em exponencial, ou tornar seu código tão confuso que ninguém conseguirá manutenção no futuro. Listas: A Estrutura Versátil e Mutável O que é uma Lista? Uma lista em Python é uma coleção ordenada, mutável e que permite elementos duplicados. Quando dizemos "mutável", significa que você pode adicionar, remover ou modificar elementos após a

Estruturas de Dados em Python: Listas, Tuplas, Sets e Dicionários

Python oferece quatro estruturas de dados fundamentais que você usará constantemente em seu dia a dia como programador. Cada uma delas foi projetada para resolver problemas específicos, e entender suas características, limitações e casos de uso é essencial para escrever código eficiente e legível. Neste artigo, vamos explorar cada uma dessas estruturas de forma prática, focando em aplicações reais que você encontrará em projetos profissionais.

A escolha da estrutura correta não é apenas uma questão de estilo — ela impacta diretamente na performance, legibilidade e manutenibilidade do seu código. Uma decisão incorreta pode transformar um algoritmo linear em exponencial, ou tornar seu código tão confuso que ninguém conseguirá manutenção no futuro.

Listas: A Estrutura Versátil e Mutável

O que é uma Lista?

Uma lista em Python é uma coleção ordenada, mutável e que permite elementos duplicados. Quando dizemos "mutável", significa que você pode adicionar, remover ou modificar elementos após a criação. A ordem dos elementos é preservada, o que torna as listas ideais quando a sequência importa.

Listas são criadas com colchetes e separadas por vírgulas. Internamente, Python armazena referências aos objetos, não os objetos em si, o que significa que você pode misturar tipos diferentes sem problemas:

# Criando listas
numeros = [1, 2, 3, 4, 5]
nomes = ["Alice", "Bob", "Carlos"]
misto = [1, "Python", 3.14, True, None]
vazia = []

# Acessando elementos (indexação começa em 0)
print(numeros[0])      # 1
print(nomes[-1])       # "Carlos" (último elemento)
print(numeros[1:3])    # [2, 3] (slice)

# Modificando elementos
numeros[0] = 10
print(numeros)         # [10, 2, 3, 4, 5]

Operações Comuns com Listas

As operações em listas são ferramentas do dia a dia. Você vai usar append(), extend(), pop(), remove() e insert() constantemente. Cada uma tem sua nuance importante:

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

# append() — adiciona um elemento no final
frutas.append("laranja")
print(frutas)  # ["maçã", "banana", "laranja"]

# extend() — adiciona múltiplos elementos
frutas.extend(["uva", "morango"])
print(frutas)  # ["maçã", "banana", "laranja", "uva", "morango"]

# insert() — adiciona em posição específica
frutas.insert(1, "abacaxi")
print(frutas)  # ["maçã", "abacaxi", "banana", "laranja", "uva", "morango"]

# remove() — remove primeira ocorrência do valor
frutas.remove("banana")
print(frutas)  # ["maçã", "abacaxi", "laranja", "uva", "morango"]

# pop() — remove por índice e retorna o valor
ultima = frutas.pop()
print(ultima)  # "morango"
print(frutas)  # ["maçã", "abacaxi", "laranja", "uva"]

# sort() — ordena IN-PLACE (modifica a lista original)
numeros = [3, 1, 4, 1, 5]
numeros.sort()
print(numeros)  # [1, 1, 3, 4, 5]

# sorted() — cria uma nova lista ordenada (não modifica a original)
numeros = [3, 1, 4, 1, 5]
ordenados = sorted(numeros)
print(numeros)      # [3, 1, 4, 1, 5]
print(ordenados)    # [1, 1, 3, 4, 5]

Iteração e Compreensão de Lista

Trabalhar com listas frequentemente envolve processar cada elemento. List comprehension é uma sintaxe Python poderosa que torna isso elegante:

# Iteração tradicional
numeros = [1, 2, 3, 4, 5]
pares = []
for num in numeros:
    if num % 2 == 0:
        pares.append(num)
print(pares)  # [2, 4]

# List comprehension — mais pythônico e rápido
pares = [num for num in numeros if num % 2 == 0]
print(pares)  # [2, 4]

# Transformando elementos
quadrados = [num ** 2 for num in numeros]
print(quadrados)  # [1, 4, 9, 16, 25]

# Com múltiplas condições
resultado = [num for num in numeros if num > 2 if num % 2 == 0]
print(resultado)  # [4]

# Caso de uso real: processar dados de API
dados_api = [
    {"nome": "Alice", "idade": 25},
    {"nome": "Bob", "idade": 30},
    {"nome": "Carlos", "idade": 22}
]
nomes_maiores = [d["nome"] for d in dados_api if d["idade"] >= 25]
print(nomes_maiores)  # ["Alice", "Bob"]

Tuplas: Imutáveis e Eficientes

Entendendo Tuplas

Uma tupla é uma sequência imutável. Uma vez criada, você não pode adicionar, remover ou modificar seus elementos. Isso pode parecer uma limitação, mas é exatamente a razão pela qual tuplas existem: quando você quer garantir que nenhum código acidentalmente modifique seus dados.

Tuplas são criadas com parênteses (que são opcionais em muitos casos) e têm performance ligeiramente melhor do que listas porque o Python pode otimizá-las:

# Criando tuplas
coordenadas = (10, 20)
ponto_3d = (1, 2, 3)
uma_coisa = (42,)  # IMPORTANTE: vírgula necessária para tupla com um elemento
vazia = ()

# Acessando elementos (igual às listas)
print(coordenadas[0])      # 10
print(ponto_3d[-1])        # 3
print(coordenadas[0:1])    # (10,)

# Tentando modificar — vai dar erro
# coordenadas[0] = 15  # TypeError: 'tuple' object does not support item assignment

Quando Usar Tuplas

Tuplas são frequentemente usadas como chaves em dicionários (listas não podem ser usadas), como argumentos de funções, ou quando você quer garantir que dados não sejam modificados acidentalmente:

# Tuplas como chaves de dicionário
mapa_localizacoes = {
    (40.7128, 74.0060): "Nova York",
    (51.5074, 0.1278): "Londres",
    (48.8566, 2.3522): "Paris"
}
print(mapa_localizacoes[(40.7128, 74.0060)])  # Nova York

# Desempacotamento de tuplas
x, y = coordenadas
print(x, y)  # 10 20

# Múltiplos retornos de função (implicitamente retornam tuplas)
def buscar_usuario(id):
    # Simulando banco de dados
    return (1, "Alice", "alice@email.com")

id_user, nome, email = buscar_usuario(1)
print(nome)  # Alice

# Iteração sobre tupla
for valor in ponto_3d:
    print(valor)  # 1, 2, 3 (cada um em uma linha)

Operações com Tuplas

Tuplas suportam algumas operações, mas não as que modificam a sequência:

tupla1 = (1, 2, 3)
tupla2 = (4, 5, 6)

# Concatenação — cria uma nova tupla
combinada = tupla1 + tupla2
print(combinada)  # (1, 2, 3, 4, 5, 6)

# Repetição
repetida = (1, 2) * 3
print(repetida)  # (1, 2, 1, 2, 1, 2)

# Contagem de elementos
tupla_com_repeticoes = (1, 2, 2, 3, 2, 4)
print(tupla_com_repeticoes.count(2))  # 3

# Índice da primeira ocorrência
print(tupla_com_repeticoes.index(3))  # 3

# Comprimento
print(len(tupla_com_repeticoes))  # 6

Sets: Unicidade e Operações Matemáticas

O Que é um Set?

Um set (conjunto) é uma coleção desordenada de elementos únicos. Não há duplicatas em um set — se você tentar adicionar um elemento que já existe, nada acontece. Sets são mutáveis, mas como são desordenados, você não pode acessar elementos por índice. Em compensação, sets são extremamente rápidos para verificar se um elemento existe.

Sets são criados com chaves {} (cuidado: {} vazio é um dicionário, não um set) ou com a função set():

# Criando sets
numeros = {1, 2, 3, 4, 5}
cores = {"vermelho", "azul", "verde"}
vazio = set()  # Correto: set() não {}

# Removendo duplicatas automaticamente
valores = [1, 2, 2, 3, 3, 3, 4]
unicos = set(valores)
print(unicos)  # {1, 2, 3, 4}

# Não há índice em sets
# print(numeros[0])  # TypeError

# Verificar existência — muito rápido
if 3 in numeros:
    print("3 existe no set")

# Para sets grandes (milhões de elementos),
# essa verificação é O(1) enquanto em listas seria O(n)
grande_set = set(range(1000000))
print(1000000 in grande_set)  # False (muito rápido!)

Operações Matemáticas com Sets

Sets implementam operações de álgebra de conjuntos. Se você estudou teoria dos conjuntos na matemática, isso vai parecer familiar:

a = {1, 2, 3, 4}
b = {3, 4, 5, 6}

# União — todos os elementos de ambos
uniao = a | b  # ou a.union(b)
print(uniao)  # {1, 2, 3, 4, 5, 6}

# Interseção — elementos em comum
interseccao = a & b  # ou a.intersection(b)
print(interseccao)  # {3, 4}

# Diferença — elementos em a mas não em b
diferenca = a - b  # ou a.difference(b)
print(diferenca)  # {1, 2}

# Diferença simétrica — elementos em um ou outro, mas não em ambos
simetrica = a ^ b  # ou a.symmetric_difference(b)
print(simetrica)  # {1, 2, 5, 6}

# Caso de uso prático: encontrar produtos em comum entre lojas
loja_a = {"notebook", "mouse", "teclado", "monitor"}
loja_b = {"notebook", "mouse", "headset", "webcam"}

produtos_em_ambas = loja_a & loja_b
print(produtos_em_ambas)  # {"notebook", "mouse"}

produtos_unicos_a = loja_a - loja_b
print(produtos_unicos_a)  # {"teclado", "monitor"}

todos_produtos = loja_a | loja_b
print(todos_produtos)  # {"notebook", "mouse", "teclado", "monitor", "headset", "webcam"}

Modificando Sets

Como sets são mutáveis, você pode adicionar e remover elementos:

numeros = {1, 2, 3}

# Adicionar um elemento
numeros.add(4)
print(numeros)  # {1, 2, 3, 4}

# Adicionar já existente não causa erro, apenas é ignorado
numeros.add(2)
print(numeros)  # {1, 2, 3, 4} — sem mudança

# Remover com garantia de existência
numeros.remove(2)
print(numeros)  # {1, 3, 4}

# Tentar remover inexistente causa erro
# numeros.remove(10)  # KeyError

# Remover com segurança
numeros.discard(10)  # Não causa erro se não existe
print(numeros)  # {1, 3, 4}

# Remover todos os elementos
numeros.clear()
print(numeros)  # set()

Dicionários: Mapeamento Chave-Valor

Estrutura e Conceito

Um dicionário é uma coleção de pares chave-valor, desordenada (em Python 3.7+, na verdade mantém ordem de inserção, mas não dever ser tratada como uma garantia formal até Python 3.7+), e extremamente eficiente para buscas. Diferentemente de listas que usam índices numéricos, dicionários usam chaves que podem ser strings, números ou tuplas.

Dicionários são criados com chaves {} separando chave e valor com ::

# Criando dicionários
usuario = {
    "nome": "Alice",
    "idade": 25,
    "email": "alice@email.com"
}

numeros_pares = {1: 2, 2: 4, 3: 6, 4: 8}
vazio = {}

# Acessando valores
print(usuario["nome"])     # Alice
print(numeros_pares[2])    # 4

# Acessar com .get() é mais seguro — retorna None se não existe
print(usuario.get("telefone"))           # None
print(usuario.get("telefone", "N/A"))    # N/A (valor padrão)

# Verificar se chave existe
if "email" in usuario:
    print(usuario["email"])  # alice@email.com

Modificando Dicionários

Dicionários são mutáveis, permitindo adicionar, modificar e remover pares chave-valor:

usuario = {"nome": "Alice", "idade": 25}

# Adicionar ou modificar
usuario["idade"] = 26
usuario["cidade"] = "São Paulo"
print(usuario)  # {"nome": "Alice", "idade": 26, "cidade": "São Paulo"}

# Remover com del
del usuario["cidade"]
print(usuario)  # {"nome": "Alice", "idade": 26}

# Remover com pop() — retorna o valor
nome = usuario.pop("nome")
print(nome)     # Alice
print(usuario)  # {"idade": 26}

# Atualizar com múltiplos pares
usuario.update({"nome": "Alice", "profissao": "Engenheira"})
print(usuario)  # {"idade": 26, "nome": "Alice", "profissao": "Engenheira"}

Iteração em Dicionários

Existem diferentes maneiras de iterar sobre um dicionário, cada uma útil em contextos específicos:

produto = {"nome": "Notebook", "preco": 2500, "estoque": 5}

# Iterar sobre chaves
for chave in produto:
    print(chave)  # nome, preco, estoque

# Iterar sobre valores
for valor in produto.values():
    print(valor)  # Notebook, 2500, 5

# Iterar sobre pares chave-valor (recomendado)
for chave, valor in produto.items():
    print(f"{chave}: {valor}")
    # nome: Notebook
    # preco: 2500
    # estoque: 5

# Dict comprehension — similar a list comprehension
precos = {"notebook": 2500, "mouse": 50, "teclado": 150}
precos_com_desconto = {item: preco * 0.9 for item, preco in precos.items()}
print(precos_com_desconto)
# {"notebook": 2250.0, "mouse": 45.0, "teclado": 135.0}

Casos de Uso Prático com Dicionários

Dicionários são fundamentais para trabalhar com dados estruturados, especialmente JSON e APIs:

# Simulando resposta de API JSON
resposta_api = {
    "usuarios": [
        {"id": 1, "nome": "Alice", "ativo": True},
        {"id": 2, "nome": "Bob", "ativo": False},
        {"id": 3, "nome": "Carlos", "ativo": True}
    ],
    "total": 3
}

# Processando dados
usuarios_ativos = [u for u in resposta_api["usuarios"] if u["ativo"]]
print(usuarios_ativos)
# [{"id": 1, "nome": "Alice", "ativo": True}, {"id": 3, "nome": "Carlos", "ativo": True}]

# Contando ocorrências de palavras (caso de uso clássico)
texto = "python python java python javascript java"
palavras = texto.split()
contagem = {}
for palavra in palavras:
    contagem[palavra] = contagem.get(palavra, 0) + 1
print(contagem)  # {"python": 3, "java": 2, "javascript": 1}

# Usando defaultdict para simplificar
from collections import defaultdict
contagem2 = defaultdict(int)
for palavra in palavras:
    contagem2[palavra] += 1
print(dict(contagem2))  # {"python": 3, "java": 2, "javascript": 1}

Comparação Prática Entre as Estruturas

Para consolidar o aprendizado, aqui está uma comparação prática mostrando qual estrutura usar em diferentes situações:

# CENÁRIO 1: Você precisa de uma coleção ordenada que você vai modificar frequentemente
# USE: LISTA
tarefas = ["estudar", "exercício", "trabalho"]
tarefas.append("ler")
tarefas.remove("exercício")

# CENÁRIO 2: Você quer retornar múltiplos valores de uma função de forma imutável
# USE: TUPLA
def buscar_coordenadas():
    return (40.7128, 74.0060)  # Retorna (latitude, longitude)

lat, lng = buscar_coordenadas()

# CENÁRIO 3: Você precisa verificar rapidamente se algo existe e não quer duplicatas
# USE: SET
emails_cadastrados = {"alice@email.com", "bob@email.com", "carlos@email.com"}
novo_email = "alice@email.com"
if novo_email not in emails_cadastrados:
    emails_cadastrados.add(novo_email)

# CENÁRIO 4: Você trabalha com dados estruturados (JSON, API, banco de dados)
# USE: DICIONÁRIO
perfil_usuario = {
    "id": 1,
    "nome": "Alice",
    "email": "alice@email.com",
    "configuracoes": {"tema": "escuro", "idioma": "pt-BR"}
}

Conclusão

Você aprendeu que listas são sua ferramenta principal quando ordem e mutabilidade importam, permitindo adicionar, remover e modificar elementos com flexibilidade. Tuplas garantem imutabilidade e são essenciais quando você quer dados que não podem ser acidentalmente alterados, além de serem ligeiramente mais rápidas e poderem servir como chaves de dicionários. Sets são especializados em unicidade e operações matemáticas de conjuntos, oferecendo O(1) para verificação de existência em comparação com O(n) em listas. Dicionários são indispensáveis para estruturar dados com pares chave-valor, sendo a base para trabalhar com APIs, JSON e dados estruturados em geral.

A escolha correta entre essas estruturas não é apenas uma questão de funcionalidade — é sobre escrever código eficiente, legível e apropriado para cada problema. Agora que você domina os conceitos, pratique escolhendo a estrutura certa para cada desafio que encontrar.

Referências


Artigos relacionados