Conjuntos (set)
Nesta aula, exploramos os conjuntos (set) em Python, abordando sua criação, operações como união e interseção, a propriedade de unicidade e a variante imutável frozenset. A aula inclui exemplos práticos, boas práticas e exercícios para fixação.
Conjuntos (set) são uma estrutura de dados fundamental em Python, inspirada na teoria dos conjuntos da matemática. Eles armazenam elementos únicos e não ordenados, sendo extremamente úteis para operações de remoção de duplicatas, testes de pertinência e operações algébricas como união, interseção e diferença. Nesta aula, veremos como criar conjuntos, realizar operações típicas, entender a unicidade de seus elementos e conhecer a variante imutável frozenset.
Ao final, você será capaz de usar conjuntos para resolver problemas que exigem eficiência e simplicidade, como remover duplicatas de listas ou verificar se dois conjuntos compartilham elementos.
Criação
Um conjunto pode ser criado de duas maneiras principais: usando chaves {} ou a função embutida set(). É importante notar que chaves vazias {} criam um dicionário, não um conjunto. Para um conjunto vazio, use set().
Os elementos de um conjunto devem ser imutáveis (como números, strings, tuplas) e não podem ser listas ou dicionários. A ordem dos elementos não é garantida e pode variar entre execuções.
# Criação de conjuntos
numeros = {1, 2, 3, 4, 5}
print(numeros) # Exemplo de saída: {1, 2, 3, 4, 5}
# Conjunto vazio (necessário usar set())
vazio = set()
print(vazio) # set()
# Conjunto a partir de uma lista (remove duplicatas)
lista = [1, 2, 2, 3, 4, 4, 5]
conjunto = set(lista)
print(conjunto) # {1, 2, 3, 4, 5}
# Conjunto com tipos mistos
mix = {1, "dois", (3, 4)}
print(mix) # {(3, 4), 1, 'dois'}
Operações (união, interseção)
Os conjuntos suportam operações matemáticas como união, interseção, diferença e diferença simétrica. Elas podem ser realizadas com operadores (|, &, -, ^) ou com métodos (union(), intersection(), difference(), symmetric_difference()).
Essas operações retornam novos conjuntos, sem modificar os originais. Também existem operadores de comparação (==, <=, >=) para verificar igualdade, subconjunto e superconjunto.
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
# União: elementos que estão em a ou em b
print(a | b) # {1, 2, 3, 4, 5, 6}
print(a.union(b)) # {1, 2, 3, 4, 5, 6}
# Interseção: elementos comuns
print(a & b) # {3, 4}
print(a.intersection(b)) # {3, 4}
# Diferença: elementos em a que não estão em b
print(a - b) # {1, 2}
print(a.difference(b)) # {1, 2}
# Diferença simétrica: elementos exclusivos de cada conjunto
print(a ^ b) # {1, 2, 5, 6}
print(a.symmetric_difference(b)) # {1, 2, 5, 6}
# Verificações
print(a == {4, 3, 2, 1}) # True (ordem não importa)
print({1, 2}.issubset(a)) # True
print(a.issuperset({3,4})) # True
Unicidade
A principal característica de um conjunto é que ele não permite elementos duplicados. Ao tentar adicionar um elemento já existente, o conjunto permanece inalterado. Isso torna os conjuntos ideais para eliminar repetições de uma sequência.
Além disso, conjuntos são implementados internamente como tabelas hash, o que proporciona testes de pertinência muito rápidos (complexidade O(1) em média).
# Removendo duplicatas de uma lista
nomes = ["Ana", "João", "Ana", "Maria", "João"]
unicos = set(nomes)
print(unicos) # {'Maria', 'João', 'Ana'}
# Adicionando elementos duplicados
s = {1, 2, 3}
s.add(2)
print(s) # {1, 2, 3} (não muda)
# Teste de pertinência
print(2 in s) # True
print(4 in s) # False
frozenset
frozenset é uma versão imutável de um conjunto. Uma vez criado, não é possível adicionar ou remover elementos. Ele é útil quando precisamos de um conjunto que possa ser usado como chave em dicionários ou como elemento de outro conjunto (já que conjuntos normais não são hashable).
Suporta todas as operações que não modificam o conjunto (união, interseção, etc.) e também pode ser criado a partir de qualquer iterável.
# Criação de frozenset
fs = frozenset([1, 2, 3, 4])
print(fs) # frozenset({1, 2, 3, 4})
# fs.add(5) # AttributeError: 'frozenset' object has no attribute 'add'
# Frozenset como chave de dicionário
d = {fs: "um conjunto imutável"}
print(d[fs]) # um conjunto imutável
# Frozenset dentro de um set
s = {frozenset({1, 2}), frozenset({3, 4})}
print(s) # {frozenset({1, 2}), frozenset({3, 4})}
# Operações comuns funcionam
outro = frozenset([3, 4, 5])
print(fs.union(outro)) # frozenset({1, 2, 3, 4, 5})
print(fs.intersection(outro)) # frozenset({3, 4})
Boas Práticas
- Use conjuntos quando precisar garantir que elementos sejam únicos ou realizar operações de conjunto de forma eficiente.
- Prefira operadores (
|,&,-,^) para legibilidade em vez de métodos, a menos que precise de uma versão mutável (métodos comointersection_updatemodificam o conjunto original). - Lembre-se: conjuntos não são ordenados. Se precisar de ordem, converta para lista ordenada com
sorted(). - Para conjuntos imutáveis que precisam ser hashable, use
frozenset.
Referências
- Documentação oficial do Python: Set Types
- Documentação oficial do Python: frozenset
- Real Python: Python Sets
- W3Schools: Python Sets
- Python Geeks: Python Sets
Exercícios
- Crie um conjunto com os números de 1 a 10. Em seguida, remova os números pares usando um loop (ou comprehension) e exiba o resultado.
- Dadas duas listas:
lista1 = [1, 2, 3, 4, 5]elista2 = [4, 5, 6, 7, 8], encontre a interseção entre elas (elementos comuns) usando conjuntos. - Escreva uma função que receba uma string e retorne um conjunto com todas as letras maiúsculas presentes nela (considere apenas caracteres alfabéticos).
- Crie um frozenset com os números 1, 2, 3 e outro com 3, 4, 5. Calcule a diferença simétrica entre eles (elementos que estão em um ou outro, mas não em ambos).
- Dado o conjunto
conj = {1, 2, 3, 4, 5}, use o métododifference_updatepara remover todos os elementos que estão no conjunto{2, 4, 6}. Exiba o conjunto resultante.
conjunto = set(range(1, 11))
impares = {x for x in conjunto if x % 2 != 0}
print(impares) # {1, 3, 5, 7, 9}
lista1 = [1, 2, 3, 4, 5]
lista2 = [4, 5, 6, 7, 8]
intersecao = set(lista1) & set(lista2)
print(intersecao) # {4, 5}
def maiusculas(texto):
return {c for c in texto if c.isupper() and c.isalpha()}
print(maiusculas("Hello World! Python é TOP.")) # {'H', 'W', 'P', 'T', 'O'}
fs1 = frozenset([1, 2, 3])
fs2 = frozenset([3, 4, 5])
diff_sim = fs1 ^ fs2
print(diff_sim) # frozenset({1, 2, 4, 5})
conj = {1, 2, 3, 4, 5}
conj.difference_update({2, 4, 6})
print(conj) # {1, 3, 5}