trubidata
Lección 5 de 12·24 min

Tuplas, sets y diccionarios

En esta guía (20)

Las listas no son la única colección de Python. En esta lección vas a conocer las tuplas (secuencias que no cambian), los sets (conjuntos sin repetidos) y los diccionarios (pares clave-valor), y vas a aprender a elegir cuál usar en cada caso. Los diccionarios se llevan la mayor parte: son, junto con las listas, la estructura que más vas a usar.

Tuplas

Una tupla es como una lista, pero inmutable: una vez creada no se le pueden agregar, quitar ni cambiar elementos. Se escribe con paréntesis:

python
punto = (3, 7)
fecha = (2026, 10, 13)
colores = ("rojo", "verde", "azul")

print(punto[0])      # 3
print(fecha[-1])     # 13
print(len(colores))  # 3
print("verde" in colores)  # True

Índices, slicing, len, in y for funcionan igual que en las listas. Lo que no funciona es modificar:

text
>>> punto[0] = 10
TypeError: 'tuple' object does not support item assignment

Para qué sirve algo que no se puede cambiar

  • Para datos que van juntos y tienen una estructura fija: una coordenada (x, y), una fecha (año, mes, día), un registro ("Ana", 34).
  • Para proteger datos: si algo no debería cambiar, una tupla lo garantiza.
  • Como claves de diccionario (enseguida vas a ver por qué una lista no puede serlo).

Un detalle de sintaxis: una tupla de un solo elemento lleva una coma, (5,). Sin la coma, (5) es solo el número 5 entre paréntesis. En realidad, lo que crea la tupla es la coma, no los paréntesis: 3, 7 también es una tupla. Por eso, en la lección 2, precio = 3,5 no daba error: creaba la tupla (3, 5).

Desempaquetado

Podés asignar los elementos de una tupla (o lista) a varias variables a la vez:

python
fecha = (2026, 10, 13)
anio, mes, dia = fecha
print(f"{dia}/{mes}/{anio}")  # 13/10/2026

La cantidad de variables tiene que coincidir con la cantidad de elementos. Si no, da ValueError.

El desempaquetado permite intercambiar dos variables en una línea:

python
a = 1
b = 2
a, b = b, a
print(a, b)  # 2 1

Y es lo que ya usaste en la lección 4 con for i, tarea in enumerate(tareas): enumerate produce tuplas (índice, elemento) y el for las desempaqueta.

Cuando recorrés una lista de tuplas, el desempaquetado deja el código muy claro:

python
stock = [("yerba", 12), ("azúcar", 0), ("café", 5)]
for producto, cantidad in stock:
    if cantidad == 0:
        print(f"Sin stock: {producto}")
text
Sin stock: azúcar

Sets

Un set (conjunto) es una colección sin elementos repetidos y sin orden. Se escribe con llaves:

python
colores = {"rojo", "verde", "rojo", "azul", "verde"}
print(len(colores))  # 3

Los repetidos se descartan solos. Como no hay orden, no hay índices: colores[0] da error. Y el orden en que se imprimen puede variar.

Quitar repetidos

El uso más común: convertir una lista a set para eliminar duplicados (es el equivalente a DISTINCT si alguna vez usaste SQL).

python
visitas = ["ana", "bruno", "ana", "carla", "bruno", "ana"]
unicos = set(visitas)
print(len(unicos))       # 3
print(sorted(unicos))    # ['ana', 'bruno', 'carla']

sorted() acepta un set y devuelve una lista ordenada: es la forma de volver a tener orden.

Para crear un set vacío se usa set(), no {} (eso crea un diccionario vacío, como vas a ver enseguida).

Agregar, quitar y buscar

python
etiquetas = set()
etiquetas.add("urgente")
etiquetas.add("trabajo")
etiquetas.add("urgente")      # ya estaba: no pasa nada
etiquetas.discard("personal") # no estaba: tampoco pasa nada
print(sorted(etiquetas))      # ['trabajo', 'urgente']
print("trabajo" in etiquetas) # True

Preguntar si algo está (in) es mucho más rápido en un set que en una lista, sobre todo cuando hay miles de elementos. La lista tiene que mirar uno por uno; el set va directo. Si vas a hacer muchas búsquedas, convertí a set.

Operaciones de conjuntos

python
curso_a = {"ana", "bruno", "carla", "diego"}
curso_b = {"carla", "diego", "elena"}

print(sorted(curso_a & curso_b))  # en los dos: ['carla', 'diego']
print(sorted(curso_a | curso_b))  # en alguno: ['ana', 'bruno', 'carla', 'diego', 'elena']
print(sorted(curso_a - curso_b))  # en A pero no en B: ['ana', 'bruno']
print(sorted(curso_a ^ curso_b))  # en uno solo: ['ana', 'bruno', 'elena']
OperadorMétodoResultado
a & ba.intersection(b)elementos en los dos
a | ba.union(b)elementos en alguno
a - ba.difference(b)elementos de a que no están en b
a ^ ba.symmetric_difference(b)elementos que están en uno solo

Si tenés dos listas y querés saber qué tienen en común, convertilas a sets y usá &: es más corto y más rápido que recorrer una lista preguntando si cada elemento está en la otra.

Diccionarios

Un diccionario guarda pares clave: valor. En vez de acceder por posición, accedés por clave:

python
precios = {"yerba": 3200, "azúcar": 1100, "café": 4500}

print(precios["café"])   # 4500
print(len(precios))      # 3
print("yerba" in precios) # True (in pregunta por las claves)
  • Las claves son únicas. Suelen ser strings o números; tienen que ser inmutables (por eso una tupla puede ser clave y una lista no).
  • Los valores pueden ser cualquier cosa: números, textos, listas, otros diccionarios.
  • Los diccionarios mantienen el orden en que insertaste las claves.

Agregar, modificar y borrar

python
stock = {"yerba": 12, "café": 5}

stock["azúcar"] = 8      # clave nueva: se agrega
stock["café"] = 7        # clave existente: se reemplaza
print(stock)             # {'yerba': 12, 'café': 7, 'azúcar': 8}

del stock["yerba"]       # borra la clave
quitado = stock.pop("café")  # borra y devuelve el valor
print(quitado, stock)    # 7 {'azúcar': 8}

Leer una clave que puede no existir

Si pedís una clave que no está, da KeyError:

text
>>> precios["mate"]
KeyError: 'mate'

Para leer sin riesgo, usá get, que devuelve None (o el valor por defecto que le pases) si la clave no existe:

python
precios = {"yerba": 3200, "azúcar": 1100}

print(precios.get("mate"))       # None
print(precios.get("mate", 0))    # 0
print(precios.get("yerba", 0))   # 3200

Recorrer un diccionario

python
precios = {"yerba": 3200, "azúcar": 1100, "café": 4500}

for producto in precios:                 # recorre las claves
    print(producto, end=" ")
print()

for precio in precios.values():          # solo los valores
    print(precio, end=" ")
print()

for producto, precio in precios.items(): # clave y valor (tuplas desempaquetadas)
    print(f"{producto}: ${precio}")
text
yerba azúcar café 
3200 1100 4500 
yerba: $3200
azúcar: $1100
café: $4500

items() es el que más vas a usar: te da cada par como una tupla (clave, valor).

Contar con un diccionario

Un patrón clásico: contar cuántas veces aparece cada elemento.

python
votos = ["rojo", "azul", "rojo", "verde", "rojo", "azul"]

conteo = {}
for color in votos:
    conteo[color] = conteo.get(color, 0) + 1

print(conteo)  # {'rojo': 3, 'azul': 2, 'verde': 1}

La línea clave: conteo.get(color, 0) devuelve el conteo actual, o 0 si es la primera vez que aparece el color. Le sumás 1 y lo guardás. (En la lección 9 vas a ver Counter, una herramienta de la biblioteca estándar que hace esto en una línea.)

Agrupar y sumar

Una variante del mismo patrón: sumar valores por categoría.

python
gastos = [
    ("comida", 4500),
    ("transporte", 1200),
    ("comida", 3100),
    ("ocio", 6000),
    ("transporte", 800),
]

por_categoria = {}
for categoria, monto in gastos:
    por_categoria[categoria] = por_categoria.get(categoria, 0) + monto

for categoria, total in por_categoria.items():
    print(f"{categoria:<12}{total:>8}")
text
comida          7600
transporte      2000
ocio            6000

Diccionarios anidados y listas de diccionarios

Un diccionario puede representar un registro con varios campos, y una lista de diccionarios, una tabla:

python
alumnos = [
    {"nombre": "Ana", "edad": 28, "notas": [8, 9, 7]},
    {"nombre": "Bruno", "edad": 34, "notas": [6, 5, 8]},
]

for alumno in alumnos:
    promedio = sum(alumno["notas"]) / len(alumno["notas"])
    print(f"{alumno['nombre']}: {promedio:.1f}")
text
Ana: 8.0
Bruno: 6.3

Fijate que dentro de la f-string usamos comillas simples para la clave (alumno['nombre']) porque la f-string ya usa dobles.

Los diccionarios también se anidan:

python
config = {
    "app": "gastos",
    "usuario": {"nombre": "Ana", "moneda": "ARS"},
}
print(config["usuario"]["moneda"])                       # ARS
print(config.get("tema", {}).get("color", "sin tema"))   # sin tema

El segundo print muestra cómo leer un campo anidado que puede faltar sin romper: si "tema" no existe, get devuelve un diccionario vacío, y sobre ese el segundo get devuelve el valor por defecto.

Dict comprehensions

Igual que con las listas, podés armar un diccionario en una línea:

python
precios = {"yerba": 3200, "azúcar": 1100, "café": 4500}
con_aumento = {producto: round(p * 1.1) for producto, p in precios.items()}
print(con_aumento)  # {'yerba': 3520, 'azúcar': 1210, 'café': 4950}

Cuál usar

Necesitás...Usá
una secuencia ordenada que va a cambiarlista
un grupo fijo de valores que van juntostupla
elementos únicos, o preguntar rápido si algo estáset
buscar un valor a partir de una clavediccionario
contar o agrupar por categoríadiccionario

Errores comunes

  • KeyError: pediste una clave que no existe con dic[clave]. Usá dic.get(clave, valor_por_defecto) o preguntá antes con in.
  • Crear un set vacío con {}. Eso es un diccionario vacío. El set vacío es set().
  • Esperar orden en un set. No lo tiene. Si necesitás mostrarlo ordenado, usá sorted(mi_set).
  • Usar una lista como clave de diccionario. Da TypeError: unhashable type: 'list'. Convertila a tupla.
  • Olvidar la coma en una tupla de un elemento. (5) es un número; (5,) es una tupla.
  • Desempaquetar con la cantidad equivocada de variables. a, b = (1, 2, 3) da ValueError: too many values to unpack.

Practicá

  1. Tenés las asistencias de dos semanas: semana1 = ["ana", "bruno", "carla", "diego"] y semana2 = ["carla", "elena", "ana", "fede"]. Mostrá, ordenados: quiénes vinieron las dos semanas, quiénes vinieron solo la primera y cuántas personas distintas asistieron en total.
  2. Dado el diccionario capitales = {"Argentina": "Buenos Aires", "Chile": "Santiago", "Uruguay": "Montevideo"}, armá el diccionario invertido (capital como clave, país como valor).
  3. Dada esta lista de ventas como tuplas (sucursal, monto), armá un diccionario con la cantidad de ventas y el total por sucursal, con la forma {"centro": {"cantidad": 2, "total": 2700}, ...}: ventas = [("centro", 1200), ("norte", 800), ("centro", 1500), ("sur", 400), ("norte", 950)]
  4. Tenés un inventario {"lapiceras": 30, "cuadernos": 12, "gomas": 0}. Escribí un programa que reciba un pedido (un diccionario como {"cuadernos": 5, "gomas": 2, "reglas": 1}) y, para cada producto, diga si se puede despachar o no (porque no hay suficiente o porque el producto no existe), descontando del inventario lo que sí se despacha.

Soluciones

Ejercicio 1:

python
semana1 = ["ana", "bruno", "carla", "diego"]
semana2 = ["carla", "elena", "ana", "fede"]

s1 = set(semana1)
s2 = set(semana2)

print("Las dos semanas:", sorted(s1 & s2))
print("Solo la primera:", sorted(s1 - s2))
print("Personas distintas:", len(s1 | s2))
text
Las dos semanas: ['ana', 'carla']
Solo la primera: ['bruno', 'diego']
Personas distintas: 6

Ejercicio 2:

python
capitales = {"Argentina": "Buenos Aires", "Chile": "Santiago", "Uruguay": "Montevideo"}
paises = {capital: pais for pais, capital in capitales.items()}
print(paises)
# {'Buenos Aires': 'Argentina', 'Santiago': 'Chile', 'Montevideo': 'Uruguay'}

Si dos claves tuvieran el mismo valor, al invertir se perdería una: las claves no se repiten.

Ejercicio 3:

python
ventas = [("centro", 1200), ("norte", 800), ("centro", 1500), ("sur", 400), ("norte", 950)]

resumen = {}
for sucursal, monto in ventas:
    if sucursal not in resumen:
        resumen[sucursal] = {"cantidad": 0, "total": 0}
    resumen[sucursal]["cantidad"] += 1
    resumen[sucursal]["total"] += monto

print(resumen)
# {'centro': {'cantidad': 2, 'total': 2700}, 'norte': {'cantidad': 2, 'total': 1750}, 'sur': {'cantidad': 1, 'total': 400}}

Ejercicio 4:

python
inventario = {"lapiceras": 30, "cuadernos": 12, "gomas": 0}
pedido = {"cuadernos": 5, "gomas": 2, "reglas": 1}

for producto, cantidad in pedido.items():
    disponible = inventario.get(producto)
    if disponible is None:
        print(f"{producto}: no existe en el inventario")
    elif disponible < cantidad:
        print(f"{producto}: stock insuficiente (hay {disponible})")
    else:
        inventario[producto] -= cantidad
        print(f"{producto}: despachado")

print(inventario)
text
cuadernos: despachado
gomas: stock insuficiente (hay 0)
reglas: no existe en el inventario
{'lapiceras': 30, 'cuadernos': 7, 'gomas': 0}

Para preguntar si algo es None se usa is None en vez de == None: es la forma recomendada, porque None es un valor único.

Resumen

  • Las tuplas son secuencias inmutables, ideales para valores que van juntos; se desempaquetan con a, b = tupla.
  • Los sets no tienen repetidos ni orden; sirven para deduplicar, buscar rápido con in y combinar con &, |, - y ^.
  • Los diccionarios guardan pares clave-valor; dic[clave] da KeyError si falta, dic.get(clave, defecto) no.
  • items() recorre clave y valor a la vez.
  • dic[k] = dic.get(k, 0) + 1 es el patrón para contar; la misma idea sirve para sumar por categoría.
  • Listas de diccionarios y diccionarios anidados representan registros y estructuras más complejas.

← Volver al temario