Aprenda a trabalhar com estruturas compostas como listas, tuplas, dicionários e conjuntos. As quatro estruturas fundamentais de Python que p...
Até agora, cada variável que criamos armazenava um único valor: um nome, uma nota, um preço. Mas e se precisarmos guardar as notas de 40 alunos? Criar 40 variáveis (nota1, nota2, ..., nota40) seria impraticável. As estruturas de dados compostas (ou coleções) resolvem esse problema ao permitir que uma única variável armazene múltiplos valores de forma organizada (MATTHES, 2019).
Python oferece quatro estruturas de dados embutidas (built-in) para armazenar coleções de valores, cada uma com características e propósitos distintos (PYTHON SOFTWARE FOUNDATION, 2024):
A lista é a estrutura de dados mais utilizada em Python. Ela armazena uma coleção ordenada e mutável de elementos, que podem ser de tipos diferentes. As listas são delimitadas por colchetes [], com os elementos separados por vírgula (MATTHES, 2019).
# Criando listas em Python
# Lista de inteiros
notas = [8.5, 7.0, 9.2, 6.8, 10.0]
# Lista de strings
frutas = ["maçã", "banana", "laranja", "uva"]
# Lista com tipos mistos (permitido, mas pouco comum)
dados = ["Ana", 25, 1.68, True]
# Lista vazia
vazia = []
# Lista com lista dentro (lista aninhada)
matriz = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
# Exibindo
print(notas) # [8.5, 7.0, 9.2, 6.8, 10.0]
print(frutas) # ['maçã', 'banana', 'laranja', 'uva']
print(len(notas)) # 5 (quantidade de elementos)
print(type(notas)) # <class 'list'>
Cada elemento de uma lista possui uma posição numérica chamada índice. Em Python, os índices começam em 0 (zero), não em 1. Isso significa que o primeiro elemento está na posição 0, o segundo na posição 1, e assim por diante. Python também suporta índices negativos, que contam a partir do final da lista: -1 é o último elemento, -2 o penúltimo, etc. (SWEIGART, 2020).
# Indexação em listas
frutas = ["maçã", "banana", "laranja", "uva", "manga"]
# Índices positivos (começam em 0)
print(frutas[0]) # maçã (primeiro)
print(frutas[2]) # laranja (terceiro)
print(frutas[4]) # manga (último)
# Índices negativos (contam do final)
print(frutas[-1]) # manga (último)
print(frutas[-2]) # uva (penúltimo)
# Modificando um elemento (listas são mutáveis!)
frutas[1] = "abacaxi"
print(frutas) # ['maçã', 'abacaxi', 'laranja', 'uva', 'manga']
O fatiamento permite extrair uma sublista a partir de uma lista existente. A sintaxe é lista[início:fim:passo], onde início é inclusivo, fim é exclusivo e passo define o intervalo entre os elementos selecionados (PYTHON SOFTWARE FOUNDATION, 2024).
# Fatiamento: lista[início:fim:passo]
numeros = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
# Do índice 2 ao 5 (exclusivo)
print(numeros[2:5]) # [20, 30, 40]
# Do início ao índice 4
print(numeros[:4]) # [0, 10, 20, 30]
# Do índice 6 ao final
print(numeros[6:]) # [60, 70, 80, 90]
# De 2 em 2 (passo)
print(numeros[::2]) # [0, 20, 40, 60, 80]
# Invertendo a lista (passo -1)
print(numeros[::-1]) # [90, 80, 70, ..., 10, 0]
# Últimos 3 elementos
print(numeros[-3:]) # [70, 80, 90]
# Cópia da lista (slicing vazio)
copia = numeros[:]
print(copia) # [0, 10, 20, ..., 90]
IndexError. Por exemplo, se a lista tem 5 elementos (índices 0 a 4), acessar lista[5] causa erro. No fatiamento, porém, índices fora do intervalo não geram erro — Python simplesmente retorna o máximo disponível (SWEIGART, 2020).
As listas possuem diversos métodos embutidos — funções que pertencem ao próprio objeto lista e são chamadas com a notação de ponto (lista.método()). Esses métodos permitem adicionar, remover, ordenar e manipular elementos de forma prática (MATTHES, 2019).
| Método | Ação | Exemplo | Resultado |
|---|---|---|---|
.append(x) | Adiciona x ao final | l.append(4) | [1,2,3,4] |
.insert(i, x) | Insere x na posição i | l.insert(1,"a") | [1,"a",2,3] |
.remove(x) | Remove a primeira ocorrência de x | l.remove(2) | [1,3] |
.pop(i) | Remove e retorna o item na posição i | l.pop(0) | retorna 1 |
.sort() | Ordena a lista (no lugar) | l.sort() | [1,2,3] |
.reverse() | Inverte a ordem (no lugar) | l.reverse() | [3,2,1] |
.index(x) | Retorna o índice da primeira ocorrência de x | l.index(2) | 1 |
.count(x) | Conta quantas vezes x aparece | l.count(2) | 1 |
.extend(l2) | Concatena outra lista ao final | l.extend([4,5]) | [1,2,3,4,5] |
.clear() | Remove todos os elementos | l.clear() | [] |
# Demonstração dos métodos de lista
compras = ["pão", "leite", "ovos"]
# Adicionando itens
compras.append("queijo")
print(compras) # ['pão', 'leite', 'ovos', 'queijo']
compras.insert(1, "manteiga")
print(compras) # ['pão', 'manteiga', 'leite', 'ovos', 'queijo']
# Removendo itens
compras.remove("leite")
print(compras) # ['pão', 'manteiga', 'ovos', 'queijo']
retirado = compras.pop() # Remove e retorna o último
print(retirado) # queijo
print(compras) # ['pão', 'manteiga', 'ovos']
# Ordenação
notas = [7.5, 9.0, 6.0, 8.5, 10.0]
notas.sort()
print(notas) # [6.0, 7.5, 8.5, 9.0, 10.0]
notas.sort(reverse=True) # Ordem decrescente
print(notas) # [10.0, 9.0, 8.5, 7.5, 6.0]
# Funções embutidas úteis com listas
print(len(notas)) # 5 (quantidade)
print(sum(notas)) # 41.0 (soma)
print(min(notas)) # 6.0 (menor)
print(max(notas)) # 10.0 (maior)
Uma das grandes vantagens das listas é a facilidade de iterar sobre seus elementos com o laço for. Essa combinação é uma das construções mais poderosas e frequentes em Python (MENEZES, 2019).
# Percorrendo listas com for
linguagens = ["Python", "Java", "C++", "JavaScript"]
for lang in linguagens:
print(f"Eu conheço {lang}!")
# Com enumerate: índice + valor
for i, lang in enumerate(linguagens, start=1):
print(f"{i}. {lang}")
# Construindo listas com for (acumulação)
quadrados = []
for n in range(1, 6):
quadrados.append(n ** 2)
print(quadrados) # [1, 4, 9, 16, 25]
# List comprehension: forma compacta e idiomática
quadrados_v2 = [n ** 2 for n in range(1, 6)]
print(quadrados_v2) # [1, 4, 9, 16, 25]
# Com condição: apenas pares
pares = [n for n in range(1, 21) if n % 2 == 0]
print(pares) # [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
[expressão for item in iterável if condição] é equivalente a um laço for com append(), mas é mais concisa e considerada mais "pythônica" pela comunidade (PYTHON SOFTWARE FOUNDATION, 2024).
Uma tupla é muito semelhante a uma lista — é uma coleção ordenada e indexável de elementos. A diferença fundamental é que a tupla é imutável: após criada, seus elementos não podem ser alterados, adicionados ou removidos. As tuplas são delimitadas por parênteses () (MATTHES, 2019).
# Criando tuplas
coordenada = (-15.79, -47.88) # Brasília
cores_rgb = (255, 128, 0) # Laranja
meses = ("jan", "fev", "mar", "abr")
singleton = (42,) # Tupla com 1 elemento (vírgula obrigatória!)
# Acessando elementos (mesma indexação das listas)
print(coordenada[0]) # -15.79 (latitude)
print(coordenada[1]) # -47.88 (longitude)
print(meses[-1]) # abr
print(meses[1:3]) # ('fev', 'mar') — fatiamento funciona!
# Imutabilidade: tentativa de alterar gera erro
# coordenada[0] = -22.90 # TypeError!
# Desempacotamento (unpacking)
lat, lon = coordenada
print(f"Latitude: {lat}, Longitude: {lon}")
# Funções úteis
print(len(meses)) # 4
print("mar" in meses) # True
print(meses.index("fev")) # 1
print(meses.count("mar")) # 1
O dicionário (dict) é uma estrutura que armazena pares de chave:valor. Diferente de listas e tuplas, que usam índices numéricos, os dicionários permitem acessar valores por meio de chaves descritivas — como um dicionário real, onde você busca uma palavra (chave) para encontrar sua definição (valor). Dicionários são delimitados por chaves {} (MATTHES, 2019).
# Criando dicionários
aluno = {
"nome": "Ana",
"idade": 22,
"curso": "Engenharia",
"notas": [8.5, 7.0, 9.2]
}
# Acessando valores pela chave
print(aluno["nome"]) # Ana
print(aluno["idade"]) # 22
print(aluno["notas"]) # [8.5, 7.0, 9.2]
# Acesso seguro com .get() (não gera erro se a chave não existir)
print(aluno.get("email", "não informado")) # não informado
# Modificando valores
aluno["idade"] = 23
print(aluno["idade"]) # 23
# Adicionando novas chaves
aluno["email"] = "ana@email.com"
print(aluno)
# Removendo um par
del aluno["email"]
# Verificando se uma chave existe
print("nome" in aluno) # True
print("email" in aluno) # False
| Método | Retorna | Descrição |
|---|---|---|
.keys() | Todas as chaves | Retorna uma visão das chaves |
.values() | Todos os valores | Retorna uma visão dos valores |
.items() | Pares (chave, valor) | Retorna tuplas com cada par |
.get(k, d) | Valor ou padrão | Acesso seguro (sem erro) |
.pop(k) | Valor removido | Remove e retorna o valor da chave k |
.update(d2) | None | Mescla outro dicionário |
# Iterando em dicionários
produto = {"nome": "Notebook", "preço": 3499.90, "estoque": 15}
# Percorrer as chaves (padrão)
for chave in produto:
print(chave)
# nome, preço, estoque
# Percorrer os valores
for valor in produto.values():
print(valor)
# Notebook, 3499.9, 15
# Percorrer chaves E valores (o mais útil!)
for chave, valor in produto.items():
print(f"{chave}: {valor}")
# Exemplo prático: contagem de votos
votos = ["Ana", "Bruno", "Ana", "Carla", "Ana", "Bruno"]
contagem = {}
for voto in votos:
contagem[voto] = contagem.get(voto, 0) + 1
print(contagem) # {'Ana': 3, 'Bruno': 2, 'Carla': 1}
contagem.get(voto, 0) + 1 é um padrão essencial: se a chave já existe, retorna seu valor atual e soma 1; se não existe, retorna o padrão (0) e soma 1, criando a chave com valor 1. Esse padrão evita a necessidade de verificar com if se a chave já está no dicionário (MENEZES, 2019).
O conjunto (set) é uma coleção não ordenada de elementos únicos (sem duplicatas). Conjuntos são inspirados na teoria dos conjuntos da matemática e suportam operações como união, interseção, diferença e diferença simétrica. São delimitados por chaves {}, mas sem pares chave:valor (PYTHON SOFTWARE FOUNDATION, 2024).
# Criando conjuntos
frutas = {"maçã", "banana", "laranja", "maçã"}
print(frutas) # {'maçã', 'banana', 'laranja'} — duplicata removida!
# Removendo duplicatas de uma lista
lista_com_repetidos = [1, 2, 3, 2, 1, 4, 3, 5]
unicos = set(lista_com_repetidos)
print(unicos) # {1, 2, 3, 4, 5}
# Adicionando e removendo
frutas.add("uva")
frutas.discard("banana")
print(frutas) # {'maçã', 'laranja', 'uva'}
# Verificação de pertencimento (muito rápida em sets!)
print("maçã" in frutas) # True
# Operações de conjuntos
python = {"Ana", "Bruno", "Carla", "Daniel"}
java = {"Bruno", "Daniel", "Eva", "Fábio"}
# União: alunos que cursam Python OU Java (ou ambos)
print(python | java)
# {'Ana', 'Bruno', 'Carla', 'Daniel', 'Eva', 'Fábio'}
# Interseção: alunos que cursam Python E Java
print(python & java)
# {'Bruno', 'Daniel'}
# Diferença: alunos SÓ em Python (não estão em Java)
print(python - java)
# {'Ana', 'Carla'}
# Diferença simétrica: exclusivos de cada conjunto
print(python ^ java)
# {'Ana', 'Carla', 'Eva', 'Fábio'}
# Subconjunto e superconjunto
basico = {"Ana", "Bruno"}
print(basico.issubset(python)) # True (é subconjunto?)
print(python.issuperset(basico)) # True (é superconjunto?)
| Critério | Lista [] | Tupla () | Dicionário {:} | Conjunto {} |
|---|---|---|---|---|
| Ordenada? | Sim | Sim | Sim (3.7+) | Não |
| Mutável? | Sim | Não | Sim | Sim |
| Duplicatas? | Permite | Permite | Chaves únicas | Não permite |
| Acesso por | Índice | Índice | Chave | — |
| Uso típico | Coleção geral | Dados fixos | Mapeamento | Unicidade |
| Exemplo | Notas de alunos | Coordenadas | Cadastro | Tags únicas |
Tupla: os dados não devem mudar? Use tupla.
Dicionário: precisa associar informações por nomes descritivos? Use dict.
Conjunto: precisa garantir elementos únicos ou fazer operações de interseção/união? Use set.
# ================================================
# Sistema de Turma - Exemplo Integrador (Parte IV)
# Conceitos: listas, tuplas, dicionários, conjuntos,
# indexação, fatiamento, métodos, iteração
# ================================================
# --- TUPLA: disciplinas disponíveis (não mudam) ---
DISCIPLINAS = ("Python", "Java", "C++", "JavaScript")
# --- LISTA DE DICIONÁRIOS: cadastro dos alunos ---
turma = [
{"nome": "Ana", "notas": [8.5, 9.0, 7.5], "disc": {"Python", "Java"}},
{"nome": "Bruno", "notas": [6.0, 7.0, 5.5], "disc": {"Python"}},
{"nome": "Carla", "notas": [9.5, 10.0, 9.8], "disc": {"Python", "C++"}},
{"nome": "Daniel", "notas": [7.0, 6.5, 8.0], "disc": {"Java", "JavaScript"}},
]
# --- Processamento ---
print("=" * 45)
print(f"{'RELATÓRIO DA TURMA':^45}")
print("=" * 45)
todas_disciplinas = set() # Conjunto para coletar disciplinas únicas
for aluno in turma:
nome = aluno["nome"]
notas = aluno["notas"]
media = sum(notas) / len(notas)
maior = max(notas)
menor = min(notas)
situacao = "Aprovado" if media >= 7.0 else "Reprovado"
print(f"\n{nome}:")
print(f" Notas: {notas} → Média: {media:.1f} ({situacao})")
print(f" Maior: {maior} | Menor: {menor}")
print(f" Disciplinas: {', '.join(aluno['disc'])}")
todas_disciplinas |= aluno["disc"] # União de conjuntos
# --- Estatísticas com conjuntos ---
print(f"\n{'='*45}")
print(f"Disciplinas matriculadas: {', '.join(sorted(todas_disciplinas))}")
nao_ofertadas = set(DISCIPLINAS) - todas_disciplinas
print(f"Sem matrícula: {', '.join(nao_ofertadas) or 'nenhuma'}")
# --- Top 3 notas (fatiamento) ---
todas_notas = []
for a in turma:
todas_notas.extend(a["notas"])
todas_notas.sort(reverse=True)
print(f"Top 3 notas da turma: {todas_notas[:3]}")
Nesta Parte IV, expandimos significativamente o repertório de ferramentas à disposição do programador Python. As listas nos deram uma coleção ordenada e mutável, com indexação, fatiamento e uma rica variedade de métodos. As tuplas oferecem a segurança da imutabilidade para dados constantes. Os dicionários introduziram o poderoso paradigma chave-valor, ideal para representar entidades do mundo real. E os conjuntos trouxeram a elegância das operações matemáticas de união, interseção e diferença, além da garantia de unicidade.
Com essas quatro estruturas, somadas aos fundamentos das partes anteriores (variáveis, operadores, condicionais, laços e funções), você já possui uma base sólida para desenvolver programas que resolvem problemas reais. O próximo passo natural é aprofundar o tratamento de exceções, a manipulação de arquivos e a orientação a objetos — temas que levarão suas habilidades de programação a um novo patamar.
Fonte:
Visto no Brasil Acadêmico

Comentários