Sets: conjuntos e operações matemáticas
1. Introdução aos Sets em Python
Em Python, um set (conjunto) é uma coleção não ordenada, mutável e que não permite elementos duplicados. Diferentemente de listas e tuplas, os sets não mantêm uma ordem específica e não suportam indexação. Eles são ideais para operações matemáticas de conjuntos e testes de pertinência eficientes.
Para criar um set, utilizamos a função set() ou chaves {} com elementos separados por vírgula:
# Criando sets
frutas = {'maçã', 'banana', 'laranja', 'maçã'} # A duplicata será removida
numeros = set([1, 2, 3, 4, 5])
vazio = set() # {} cria um dicionário vazio, não um set!
print(frutas) # {'banana', 'maçã', 'laranja'} - ordem pode variar
print(numeros) # {1, 2, 3, 4, 5}
Os elementos de um set devem ser imutáveis (números, strings, tuplas). Listas, dicionários e outros sets não podem ser elementos:
# Elementos permitidos
set_valido = {1, 'Python', (1, 2, 3), 3.14}
# Elementos não permitidos (geram TypeError)
# set_invalido = {[1, 2], {'chave': 'valor'}} # Descomente para ver o erro
2. Características Fundamentais dos Sets
Impossibilidade de duplicatas: Sets eliminam automaticamente elementos repetidos, tornando-os perfeitos para garantir unicidade:
repetidos = {1, 2, 2, 3, 3, 3, 4}
print(repetidos) # {1, 2, 3, 4}
Não ordenação: A ordem dos elementos em um set não é garantida e pode variar entre execuções. Isso significa que não podemos acessar elementos por índice:
meu_set = {'a', 'b', 'c'}
# print(meu_set[0]) # TypeError: 'set' object is not subscriptable
Mutabilidade: Diferente de frozenset, os sets podem ser modificados após a criação, permitindo adição e remoção de elementos.
3. Métodos Essenciais para Manipulação
Adição de elementos
conjunto = {1, 2, 3}
# add() - adiciona um único elemento
conjunto.add(4)
print(conjunto) # {1, 2, 3, 4}
# update() - adiciona múltiplos elementos de um iterável
conjunto.update([5, 6, 7])
print(conjunto) # {1, 2, 3, 4, 5, 6, 7}
# Tentativa de adicionar elemento existente é ignorada
conjunto.add(1)
print(conjunto) # {1, 2, 3, 4, 5, 6, 7} - sem alteração
Remoção de elementos
conjunto = {1, 2, 3, 4, 5}
# remove() - lança KeyError se o elemento não existir
conjunto.remove(3)
print(conjunto) # {1, 2, 4, 5}
# conjunto.remove(10) # KeyError: 10
# discard() - seguro, não lança erro se o elemento não existir
conjunto.discard(10) # Silenciosamente ignorado
conjunto.discard(1)
print(conjunto) # {2, 4, 5}
# pop() - remove e retorna um elemento aleatório
elemento = conjunto.pop()
print(f"Elemento removido: {elemento}")
# clear() - remove todos os elementos
conjunto.clear()
print(conjunto) # set()
Verificação de pertinência
numeros = {1, 2, 3, 4, 5}
print(3 in numeros) # True
print(10 in numeros) # False
print(10 not in numeros) # True
4. Operações de Conjuntos: União e Interseção
União (union() e operador |)
A união combina todos os elementos únicos de dois ou mais conjuntos:
tags_python = {'python', 'programação', 'backend', 'dados'}
tags_web = {'javascript', 'frontend', 'backend', 'css'}
# Usando método
todas_tags = tags_python.union(tags_web)
print(todas_tags)
# {'python', 'programação', 'backend', 'dados', 'javascript', 'frontend', 'css'}
# Usando operador
todas_tags_op = tags_python | tags_web
print(todas_tags_op) # Mesmo resultado
Interseção (intersection() e operador &)
A interseção retorna apenas os elementos comuns entre os conjuntos:
preferencias_a = {'filme', 'música', 'livro', 'esporte'}
preferencias_b = {'música', 'teatro', 'esporte', 'dança'}
comuns = preferencias_a.intersection(preferencias_b)
print(comuns) # {'música', 'esporte'}
# Usando operador
comuns_op = preferencias_a & preferencias_b
print(comuns_op) # {'música', 'esporte'}
5. Operações de Conjuntos: Diferença e Diferença Simétrica
Diferença (difference() e operador -)
A diferença retorna elementos presentes no primeiro conjunto mas não no segundo:
usuarios_ativos = {'ana', 'joão', 'maria', 'pedro'}
usuarios_premium = {'joão', 'maria'}
usuarios_comuns = usuarios_ativos.difference(usuarios_premium)
print(usuarios_comuns) # {'ana', 'pedro'}
# Usando operador
usuarios_comuns_op = usuarios_ativos - usuarios_premium
print(usuarios_comuns_op) # {'ana', 'pedro'}
Diferença Simétrica (symmetric_difference() e operador ^)
A diferença simétrica retorna elementos que estão em um ou outro conjunto, mas não em ambos:
log_ontem = {'erro_1', 'erro_2', 'aviso_1', 'info_1'}
log_hoje = {'erro_2', 'erro_3', 'aviso_1', 'info_2'}
mudancas = log_ontem.symmetric_difference(log_hoje)
print(mudancas) # {'erro_1', 'erro_3', 'info_1', 'info_2'}
# Usando operador
mudancas_op = log_ontem ^ log_hoje
print(mudancas_op) # Mesmo resultado
6. Relações entre Conjuntos: Subconjuntos e Disjunção
Verificação de subconjunto e superconjunto
numeros = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
pares = {2, 4, 6, 8, 10}
primos = {2, 3, 5, 7}
print(pares.issubset(numeros)) # True
print(numeros.issuperset(pares)) # True
# Usando operadores
print(pares <= numeros) # True (subconjunto)
print(numeros >= pares) # True (superconjunto)
print(pares < numeros) # True (subconjunto próprio)
print(primos < pares) # False
Disjunção (isdisjoint())
Dois conjuntos são disjuntos se não possuem elementos em comum:
categoria_a = {'eletrônicos', 'informática'}
categoria_b = {'moda', 'beleza'}
print(categoria_a.isdisjoint(categoria_b)) # True
categoria_c = {'eletrônicos', 'games'}
print(categoria_a.isdisjoint(categoria_c)) # False (eletrônicos está em ambos)
7. Sets vs. Outras Estruturas de Dados
Sets vs. Listas
A principal diferença está no desempenho para testes de pertinência:
import time
# Lista grande
lista = list(range(1000000))
set_grande = set(range(1000000))
# Teste de pertinência
inicio = time.time()
print(999999 in lista) # O(n) - leva tempo proporcional ao tamanho
print(f"Lista: {time.time() - inicio:.6f} segundos")
inicio = time.time()
print(999999 in set_grande) # O(1) - extremamente rápido
print(f"Set: {time.time() - inicio:.6f} segundos")
Sets vs. Tuplas
Tuplas são imutáveis e ordenadas, sets são mutáveis e não ordenados. Sets garantem unicidade, tuplas permitem duplicatas.
Sets vs. Dicionários
Sets podem ser usados como chaves de dicionários indiretamente através de frozenset:
# Usando frozenset como chave de dicionário
dicionario = {
frozenset({'a', 'b'}): 'valor_1',
frozenset({'c', 'd'}): 'valor_2'
}
print(dicionario[frozenset({'a', 'b'})]) # 'valor_1'
8. Boas Práticas e Casos de Uso Comuns
Eliminação de duplicatas em listas
lista_com_duplicatas = [1, 2, 2, 3, 3, 3, 4, 5, 5]
lista_sem_duplicatas = list(set(lista_com_duplicatas))
print(lista_sem_duplicatas) # [1, 2, 3, 4, 5] - ordem pode variar
Testes de pertinência eficientes
# Em vez de usar lista para verificar milhões de elementos
ids_bloqueados = set(range(1000000))
def verificar_acesso(user_id):
return user_id not in ids_bloqueados # O(1) - extremamente rápido
Análise de dados com conjuntos
# IDs de usuários que realizaram ações específicas
usuarios_compra = {101, 102, 103, 104, 105}
usuarios_visita = {102, 104, 106, 107, 108}
usuarios_cadastro = {101, 103, 105, 109}
# Usuários que compraram mas não visitaram
apenas_compra = usuarios_compra - usuarios_visita
print(f"Compraram sem visitar: {apenas_compra}") # {101, 103, 105}
# Usuários que fizeram todas as ações
completos = usuarios_compra & usuarios_visita & usuarios_cadastro
print(f"Completaram tudo: {completos}") # set() - vazio neste caso
Cuidados importantes
- Elementos mutáveis não são permitidos: Use tuplas em vez de listas se precisar armazenar sequências
- Perda de ordem original: Ao converter lista para set, a ordem original é perdida. Se a ordem for importante, use
dict.fromkeys()para Python 3.7+ ou OrderedDict
# Mantendo ordem ao remover duplicatas (Python 3.7+)
lista = [3, 1, 2, 1, 3, 2]
lista_ordenada_sem_dup = list(dict.fromkeys(lista))
print(lista_ordenada_sem_dup) # [3, 1, 2] - ordem preservada
Referências
- Documentação Oficial Python - Set Types — Documentação completa sobre sets e frozensets na biblioteca padrão Python
- Real Python - Sets in Python — Tutorial abrangente com exemplos práticos e casos de uso avançados
- GeeksforGeeks - Python Sets — Guia detalhado com operações, métodos e exemplos de código
- W3Schools - Python Sets — Referência rápida com exemplos interativos para iniciantes
- Python Tips - Sets and Frozen Sets — Dicas avançadas sobre operações matemáticas com conjuntos em Python