Python Métodos de Conjunto e Tupla
Esta é a página de consulta rápida dos conjuntos (set e frozenset) e das tuplas (tuple). Um conjunto guarda valores sem repetição e sem ordem, e tem 17 métodos para acrescentar, remover e fazer as contas de conjuntos da escola (união, interseção, diferença). A tupla é uma sequência que não muda depois de criada, e tem só 2 métodos. As explicações passo a passo estão nas aulas Conjuntos (set), União, Interseção e Diferença e Tuplas.
- Exemplo é o que você digitaria depois do
>>>do modo interativo, uma linha depois da outra; Resultado é o que o Python 3.14.4 respondeu no computador da Ana. - Os exemplos de conjunto usam números pequenos de propósito: com eles, o Python mostra sempre na mesma ordem. Com textos, a ordem muda de uma execução para outra (veja o quadro abaixo).
- Quando o exemplo dá erro, o resultado mostra a última linha da mensagem do Python (em inglês).
A Ana rodou o mesmo programa três vezes seguidas:
feira = {"pão", "leite", "café", "ovo"}
print(feira)
$ python3 feira.py
{'café', 'leite', 'pão', 'ovo'}
$ python3 feira.py
{'leite', 'ovo', 'café', 'pão'}
$ python3 feira.py
{'ovo', 'leite', 'pão', 'café'}
Os itens são os mesmos, mas a ordem mudou a cada vez. Isso é normal: o conjunto não promete ordem nenhuma (por segurança, o Python sorteia o jeito de guardar textos a cada vez que começa). Quando a ordem importa, mostre com sorted(feira), que devolve uma lista em ordem alfabética: ['café', 'leite', 'ovo', 'pão']. Pelo mesmo motivo, conjunto não aceita índice: feira[0] dá TypeError: 'set' object is not subscriptable ("o objeto set não aceita [ ]").
Criar um conjunto
| Escrita | O que faz | Exemplo | Resultado | Aula |
|---|---|---|---|---|
{a, b, c} | Um conjunto com esses valores. Os repetidos somem. | {3, 1, 3, 2} | {1, 2, 3} | Conjuntos |
set(itens) | Um conjunto com os itens de uma lista (ou texto, tupla…). O jeito clássico de tirar repetidos. | set([5, 5, 7]) | {5, 7} | Conjuntos |
set() | Um conjunto vazio. | set() | set() | |
{} | Não é um conjunto vazio: é um dicionário vazio! | type({}) | <class 'dict'> | Dicionários |
{expr for x in …} | Monta um conjunto a partir de um laço. | {n % 3 for n in range(10)} | {0, 1, 2} | Dict e Set Comprehension |
len(s) | Quantos valores diferentes. | len({1, 2, 2, 3}) | 3 | |
x in s | "Tem?" No conjunto, essa pergunta é muito rápida, mesmo com milhões de itens. | 3 in {1, 2, 3} | True | is e in |
Acrescentar e remover
| Método | O que faz | Exemplo | Resultado | Aula |
|---|---|---|---|---|
add(x) | Acrescenta um valor (add = "adicionar"). | s = {1, 2}s.add(3)s | {1, 2, 3} | Conjuntos |
| se já tem, nada muda (e não dá erro) | s.add(2)s | {1, 2, 3} | ||
| 3.14 listas não podem entrar num conjunto | s.add([7]) | TypeError: cannot use 'list' as a set element (unhashable type: 'list') | Mutável × Imutável | |
update(itens, …) | Acrescenta todos os valores de uma ou mais listas/conjuntos. | s.update([4, 5], {6})s | {1, 2, 3, 4, 5, 6} | |
remove(x) | Tira o valor. Se não tem, dá erro. | s = {1, 2, 3, 4}s.remove(2)s | {1, 3, 4} | Conjuntos |
| valor que não está lá | s.remove(9) | KeyError: 9 | ||
discard(x) | Tira o valor, se tiver. Se não tem, não dá erro (discard = "descartar"). | s.discard(9)s.discard(3)s | {1, 4} | |
pop() | Tira e devolve um valor qualquer (não dá para escolher qual). | s = {7}s.pop()s | 7set() | |
| conjunto vazio | set().pop() | KeyError: 'pop from an empty set' | ||
clear() | Esvazia o conjunto. | s = {1, 2, 3}s.clear()s | set() | |
copy() | Uma cópia: mudar a cópia não muda o original. | c = {1, 2}d = c.copy()d.add(9)c | {1, 2} | Cópia Rasa e Cópia Profunda |
A diferença entre remove e discard, no terminal:
$ python3 -q
>>> s = {1, 2, 3, 4}
>>> s.remove(9)
Traceback (most recent call last):
File "<python-input-1>", line 1, in <module>
s.remove(9)
~~~~~~~~^^^
KeyError: 9
>>> s.discard(9)
>>> s
{1, 2, 3, 4}
>>> exit()
KeyError: 9 = "erro de chave: 9" (o conjunto usa o mesmo erro dos dicionários). O discard(9) não reclamou, e o conjunto ficou igual.
União, interseção e diferença
Nos exemplos: a = {1, 2, 3, 4} e b = {3, 4, 5}. Cada operação tem um método e um operador que fazem a mesma coisa e devolvem um conjunto novo (o a e o b não mudam).
| Método | Operador | O que dá | Exemplo | Resultado |
|---|---|---|---|---|
a.union(b) | a | b | União: o que está em a ou em b (ou nos dois) | a | b | {1, 2, 3, 4, 5} |
a.intersection(b) | a & b | Interseção: o que está nos dois | a & b | {3, 4} |
a.difference(b) | a - b | Diferença: o que está em a e não em b | a - bb - a | {1, 2}{5} |
a.symmetric_difference(b) | a ^ b | Diferença simétrica: o que está em só um dos dois | a ^ b | {1, 2, 5} |
O operador é mais curto e só aceita conjuntos dos dois lados: a | [9, 10] dá TypeError: unsupported operand type(s) for |: 'set' and 'list'. O método aceita qualquer sequência e vários argumentos: a.union([9, 10]) dá {1, 2, 3, 4, 9, 10}, e a.intersection({3}, {3, 4}) dá {3}.
As versões que mudam o conjunto
Os métodos terminados em _update (e os operadores com =) guardam o resultado no próprio conjunto da esquerda, em vez de criar um novo. Devolvem None.
| Método | Operador | Exemplo | Resultado |
|---|---|---|---|
a.update(b) | a |= b | a = {1, 2}a |= {5}a | {1, 2, 5} |
a.intersection_update(b) | a &= b | a = {1, 2, 3, 4}a.intersection_update({2, 3, 9})a | {2, 3} |
a.difference_update(b) | a -= b | a = {1, 2, 3, 4}a.difference_update({1, 2})a | {3, 4} |
a.symmetric_difference_update(b) | a ^= b | a = {1, 2, 3}a.symmetric_difference_update({3, 4})a | {1, 2, 4} |
Comparar conjuntos
| Método | Operador | Pergunta | Exemplo | Resultado |
|---|---|---|---|---|
a.issubset(b) | a <= b | "Tudo de a está em b?" (a é subconjunto de b) | {1, 2} <= {1, 2, 3} | True |
a < b | …e b tem algo a mais? | {1, 2} < {1, 2} | False | |
a.issuperset(b) | a >= b | "a contém tudo de b?" (superconjunto) | {1, 2, 3}.issuperset({1, 3}) | True |
a.isdisjoint(b) | — | "Não têm nada em comum?" (disjoint = "separados") | {1, 2}.isdisjoint({3, 4}){1, 2}.isdisjoint({2, 3}) | TrueFalse |
| — | a == b | "Têm os mesmos valores?" A ordem não importa. | {1, 2} == {2, 1} | True |
frozenset: o conjunto congelado
O frozenset é um conjunto que não muda depois de criado. Ele tem só os 8 métodos que não alteram o conjunto: copy, union, intersection, difference, symmetric_difference, issubset, issuperset e isdisjoint. Por não mudar, ele pode ser chave de dicionário ou item de outro conjunto.
| Escrita | O que faz | Exemplo | Resultado |
|---|---|---|---|
frozenset(itens) | Cria o conjunto congelado. | f = frozenset([3, 1, 3])f | frozenset({1, 3}) |
f | s | As operações funcionam e devolvem um frozenset novo. | f | {5} | frozenset({1, 3, 5}) |
f.add(x) | Não existe: ele não muda. | f.add(5) | AttributeError: 'frozenset' object has no attribute 'add' |
| como chave | Pode ser chave de dicionário. | {frozenset([1, 2]): "par"} | {frozenset({1, 2}): 'par'} |
== | Compara com um set pelos valores. | frozenset([1, 2]) == {1, 2} | True |
Tuplas: os 2 métodos e as operações
Uma tupla se escreve com parênteses: ponto = (3, 4). Ela tem índices e fatias como a lista, mas não muda: por isso não tem append, remove, sort… Os únicos métodos são os dois que só leem. Nos exemplos, notas = (7.5, 9.0, 6.5, 9.0).
| Escrita | O que faz | Exemplo | Resultado | Aula |
|---|---|---|---|---|
count(x) | Quantas vezes x aparece. | notas.count(9.0) | 2 | Tuplas |
index(x) | A posição do primeiro x. | notas.index(9.0) | 1 | Tuplas |
| se não tem, dá erro | notas.index(10) | ValueError: tuple.index(x): x not in tuple | ||
t[i], t[a:b] | Um item; uma fatia (outra tupla). | notas[1:3] | (9.0, 6.5) | Acessando Itens |
t[i] = x | Não pode: tupla não muda. | ponto = (3, 4)ponto[0] = 9 | TypeError: 'tuple' object does not support item assignment | Mutável × Imutável |
len, in | Quantos itens; "tem?" | len(notas), 9.0 in notas | 4, True | |
min, max, sum, sorted | Funcionam como nas listas. sorted devolve uma lista. | min(notas), max(notas), sum(notas)sorted(notas) | (6.5, 9.0, 32.0)[6.5, 7.5, 9.0, 9.0] | Funções Embutidas |
a + b, t * n | Uma tupla nova, juntando ou repetindo. | (1, 2) + (3,), (0,) * 3 | (1, 2, 3), (0, 0, 0) | |
(x,) | Tupla de um item: a vírgula é obrigatória. Sem ela, os parênteses são só parênteses. | type((5))type((5,)) | <class 'int'><class 'tuple'> | Tuplas |
a, b | Quem faz a tupla é a vírgula; os parênteses são opcionais. | 5, | (5,) | |
tuple(itens) | Converte para tupla; sem nada, a tupla vazia. | tuple("Ana"), tuple() | ('A', 'n', 'a'), () | |
x, y = t | Desempacota: cada variável recebe um item. | nome, idade = ("Ana", 30)nome, depois idade | 'Ana'30 | Desempacotamento |
| a quantidade tem que bater | x, y = (1, 2, 3) | ValueError: too many values to unpack (expected 2, got 3) | ||
a < b | Compara item por item. | (1, 2) < (1, 3) | True | Comparações |
| como chave | Uma tupla pode ser chave de dicionário ou item de conjunto… | {(1, 2): "A1"} | {(1, 2): 'A1'} | Dicionários |
| …desde que tudo dentro dela também não mude | t = ([1], 2)t[0].append(5)thash(t) | ([1, 5], 2)TypeError: unhashable type: 'list' | Mutável × Imutável |
Para tuplas em que cada posição tem um significado (nome, idade, cidade), o módulo collections tem a namedtuple, que deixa escrever aluno.nome em vez de aluno[0]. Veja O Módulo collections.
Lista, tupla, conjunto ou dicionário?
| Tipo | Escrita | Tem ordem? | Repete? | Muda? | Use para |
|---|---|---|---|---|---|
list | [1, 2] | sim | sim | sim | uma sequência que cresce e muda (a lista de compras) |
tuple | (1, 2) | sim | sim | não | um grupo fixo de valores (um ponto, uma data, um registro) |
set | {1, 2} | não | não | sim | tirar repetidos, perguntar "tem?" depressa, comparar grupos |
frozenset | frozenset({1, 2}) | não | não | não | um conjunto que vai ser chave de dicionário |
dict | {"a": 1} | a da entrada | chaves não | sim | achar um valor pelo nome (preço pelo produto) — veja Métodos de Dicionário |
Experimente
Missão: na escola da Ana, há o time de futebol e o clube de xadrez. Troque os dois set() pelas operações certas: quem está nos dois (interseção, &) e quem está só no futebol (diferença, -). A saída deve ter Nos dois: ['Bia', 'Davi'] e Só futebol: ['Ana', 'Caio']. O sorted() já está lá para a ordem não variar.
futebol = {"Ana", "Bia", "Caio", "Davi"}
xadrez = {"Bia", "Davi", "Eva"}
nos_dois = set()
so_futebol = set()
print("Nos dois:", sorted(nos_dois))
print("Só futebol:", sorted(so_futebol))
print("Todos:", sorted(futebol | xadrez))
futebol = {"Ana", "Bia", "Caio", "Davi"}
xadrez = {"Bia", "Davi", "Eva"}
nos_dois = futebol & xadrez
so_futebol = futebol - xadrez
print("Nos dois:", sorted(nos_dois))
print("Só futebol:", sorted(so_futebol))
print("Todos:", sorted(futebol | xadrez))
A solução, no computador da Ana:
$ python3 clubes.py Nos dois: ['Bia', 'Davi'] Só futebol: ['Ana', 'Caio'] Todos: ['Ana', 'Bia', 'Caio', 'Davi', 'Eva']
Livre: conjuntos e tuplas juntos. Mude as notas, acrescente uma cidade na tupla (e uma variável no desempacotamento).
notas = (7, 9, 7, 10, 6, 9, 7)
diferentes = set(notas)
print("Notas diferentes:", sorted(diferentes), "-", len(diferentes), "valores")
print("Alguém tirou 10?", 10 in diferentes)
aluno = ("Ana", 30, "Teresina")
nome, idade, cidade = aluno
print(f"{nome} tem {idade} anos e mora em {cidade}")
print("Quantas vezes o 7 aparece:", notas.count(7))
print("Posição do primeiro 9:", notas.index(9))
$ python3 turma.py Notas diferentes: [6, 7, 9, 10] - 4 valores Alguém tirou 10? True Ana tem 30 anos e mora em Teresina Quantas vezes o 7 aparece: 3 Posição do primeiro 9: 1
Resumo
- Conjunto: sem repetidos e sem ordem. Para mostrar em ordem,
sorted().{}é dicionário; o conjunto vazio éset(). - Acrescentar:
add(um),update(vários). Remover:remove(erro se não tem),discard(sem erro),pop,clear. - Contas:
|união,&interseção,-diferença,^diferença simétrica; os métodos com_updatemudam o próprio conjunto. - Comparar:
issubset(<=),issuperset(>=),isdisjoint. frozenseté o conjunto que não muda: só os 8 métodos que leem, e pode ser chave.- Tupla: não muda, tem só
counteindex; tupla de um item precisa da vírgula:(5,).