Uma coleção sem repetidos
Um conjunto (set) guarda cada valor no máximo uma vez e não tem posição: {"AAPL", "MSFT", "GOOG"}. Adicionar um valor que já existe não muda nada. set(items) transforma qualquer iterável em conjunto, a forma mais rápida de remover duplicados, e len passa a contar os valores distintos. Como um conjunto não tem ordem, não se pode indexá-lo, e a ordem que se vê ao imprimir não é confiável. Um conjunto vazio é set(): {} é um dicionário vazio.
symbols = ["AAPL", "MSFT", "AAPL", "GOOG", "MSFT"]
# set() removes repeats
unique = set(symbols)
print(len(symbols), len(unique)) # 5 3
# Adding something already there changes nothing
unique.add("AAPL")
unique.add("TSLA")
print(len(unique)) # 4
# {} is a dict; an empty set is set()
print(type({}), type(set())) # <class 'dict'> <class 'set'>Testes de pertinência rápidos
x in some_set responde quase instantaneamente, mesmo com milhões de valores, porque um conjunto encontra um valor pelo hash em vez de varrer tudo. O mesmo teste em uma lista examina os itens um a um e fica mais lento conforme a lista cresce. Por isso, se você pergunta in muitas vezes à mesma coleção, como conferir cada ordem recebida contra uma lista de símbolos proibidos, converta essa coleção em conjunto uma só vez. Os membros de um conjunto devem ser hashable, como as chaves de um dicionário.
# Membership: a set is the fast structure for "is it in there?"
banned = {"GME", "AMC", "BBBY"}
orders = ["AAPL", "GME", "MSFT", "AMC"]
allowed = [symbol for symbol in orders if symbol not in banned]
print(allowed) # ['AAPL', 'MSFT']
# Sets only keep hashable values
try:
{["AAPL"]}
except TypeError as error:
print("not hashable:", error)Aritmética de conjuntos
Os conjuntos se combinam como na matemática. a | b é a união (em um ou outro), a & b a interseção (em ambos), a - b a diferença (em a mas não em b) e a ^ b a diferença simétrica (em exatamente um). Cada uma também existe como método, por exemplo a.union(b), que aceita qualquer iterável. Todas devolvem um conjunto novo e deixam a e b intactos. É exatamente o que se quer para comparar dois universos de símbolos ou duas listas de posições.
# Comparing yesterday's and today's universe
yesterday = {"AAPL", "MSFT", "GOOG", "IBM"}
today = {"AAPL", "MSFT", "TSLA"}
print(sorted(yesterday | today)) # ['AAPL', 'GOOG', 'IBM', 'MSFT', 'TSLA']
print(sorted(yesterday & today)) # ['AAPL', 'MSFT']
print(sorted(today - yesterday)) # ['TSLA'] (new listings)
print(sorted(yesterday - today)) # ['GOOG', 'IBM'] (dropped)
print(sorted(yesterday ^ today)) # ['GOOG', 'IBM', 'TSLA']Alterar um conjunto e manter a ordem
add(x) insere um valor, update(items) insere vários, discard(x) remove um valor se existir (em silêncio) e remove(x) remove, mas gera KeyError se estiver ausente. Um conjunto esquece a ordem, então quando a ordem importa é preciso uma lista: sorted(some_set) dá uma lista ordenada, e para remover duplicados mantendo a ordem da primeira aparição, percorra os valores e lembre em um conjunto o que já viu (seen). Essa checagem é rápida porque é um conjunto.
# Remove repeats and keep the first-seen order
symbols = ["MSFT", "AAPL", "MSFT", "GOOG", "AAPL"]
seen = set()
ordered = []
for symbol in symbols:
if symbol not in seen:
seen.add(symbol)
ordered.append(symbol)
print(ordered) # ['MSFT', 'AAPL', 'GOOG']
# discard is quiet, remove is strict
seen.discard("TSLA")
try:
seen.remove("TSLA")
except KeyError:
print("TSLA was not in the set")sorted(...) para obter uma lista estável. Os labs pedem listas ordenadas justamente por isso.set(items): manter cada valor uma vez;len(set(items))conta os valores distintos.x in sé rápido;a | b,a & b,a - b,a ^ bconstroem conjuntos novos.- Conjuntos não têm ordem: use
sorted(s)quando precisar de uma lista.
A seguir: ler e escrever arquivos de texto, para que seus programas guardem dados entre execuções.
Lab: o que é avaliado
- Contar símbolos distintos com
distinct_count25 pts - Identificar os símbolos que apareceram com
new_listings25 pts - Encontrar a interseção de duas carteiras com
common_symbols25 pts - Remover repetidos mantendo a ordem com
dedupe_keep_order25 pts