Una colección sin repetidos
Un conjunto (set) contiene cada valor como mucho una vez y no tiene posición: {"AAPL", "MSFT", "GOOG"}. Añadir un valor que ya está no cambia nada. set(items) convierte cualquier iterable en conjunto, la forma más rápida de eliminar duplicados, y len cuenta entonces los valores distintos. Como un conjunto no tiene orden, no se puede indexar, y el orden que ves al imprimirlo no es fiable. Un conjunto vacío es set(): {} es un diccionario vacío.
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'>Pruebas de pertenencia rápidas
x in some_set responde casi al instante, incluso con millones de valores, porque un conjunto encuentra un valor por su hash en lugar de recorrerlo todo. La misma prueba en una lista examina los elementos uno a uno y se vuelve más lenta cuanto más crece. Por eso, si preguntas muchas veces in contra la misma colección, como comprobar cada orden entrante contra una lista de símbolos prohibidos, convierte esa colección en conjunto una sola vez. Los miembros de un conjunto deben ser hashables, como las claves de un diccionario.
# 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
Los conjuntos se combinan como en matemáticas. a | b es la unión (en alguno), a & b la intersección (en ambos), a - b la diferencia (en a pero no en b) y a ^ b la diferencia simétrica (en exactamente uno). Cada una existe también como método, por ejemplo a.union(b), que acepta cualquier iterable. Todas devuelven un conjunto nuevo y dejan a y b intactos. Es justo lo que necesitas para comparar dos universos de símbolos o dos listas de posiciones.
# 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']Cambiar un conjunto y conservar el orden
add(x) inserta un valor, update(items) inserta varios, discard(x) quita un valor si está (sin avisar) y remove(x) lo quita pero lanza KeyError si no está. Un conjunto olvida el orden, así que cuando el orden importa necesitas una lista: sorted(some_set) da una lista ordenada, y para quitar duplicados conservando el orden de primera aparición, recorre los valores y recuerda en un conjunto lo que ya has visto (seen). Esa comprobación es rápida porque es un 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 obtener una lista estable. Los labs piden listas ordenadas justo por esto.set(items): guardar cada valor una vez;len(set(items))cuenta los valores distintos.x in ses rápido;a | b,a & b,a - b,a ^ bconstruyen conjuntos nuevos.- Los conjuntos no tienen orden: usa
sorted(s)cuando necesites una lista.
A continuación: leer y escribir archivos de texto, para que tus programas conserven datos entre ejecuciones.
Lab: qué se califica
- Contar símbolos distintos con
distinct_count25 pts - Detectar los símbolos que aparecieron con
new_listings25 pts - Hallar la intersección de dos carteras con
common_symbols25 pts - Quitar repetidos conservando el orden con
dedupe_keep_order25 pts