¡Esta es una revisión vieja del documento!
Tabla de Contenidos
Colecciones de datos
Hasta ahora, cada variable almacenaba un solo valor: un número, un texto, un booleano. Pero los programas reales rara vez trabajan con datos aislados. Una lista de invitados, las notas de un examen, los datos de un usuario (nombre, edad, correo) o el historial de movimientos de una cuenta son conjuntos de valores relacionados. Para manejarlos, Python ofrece cuatro colecciones fundamentales: listas, tuplas, conjuntos y diccionarios.
Este módulo forma parte del curso de programación desde cero con Python
3. Conocimientos previos
- Del Módulo 4: Variables, tipos, operadores, identidad (is) y el modelo de objetos (variables como referencias).
- Del Módulo 5: Cadenas, índices y segmentación (los mismos conceptos se aplican a listas y tuplas).
- Del Módulo 6: Condiciones y truthiness (una colección vacía es falsy).
- Del Módulo 7: Bucles for y while, contadores, acumuladores y enumerate() (introducido como reto opcional).
- Ningún conocimiento de listas, tuplas, conjuntos, diccionarios ni comprensiones.
4. Introducción motivadora: el programa que solo recuerda un dato
Un programa que guarda la nota de un examen no sirve para calcular la media de la clase. Un programa que guarda un nombre no sirve para gestionar una lista de invitados. La necesidad de agrupar valores relacionados es tan antigua como la programación. Las colecciones resuelven ese problema: permiten almacenar muchos valores bajo un mismo nombre, recorrerlos, buscar en ellos y transformarlos.
Cada colección tiene una personalidad distinta. Una lista es como una fila de cajas numeradas: puedes cambiar el contenido de una caja, añadir cajas al final o insertarlas en medio. Una tupla es como un formulario sellado: una vez rellenado, no puedes modificar sus campos. Un conjunto es como una bolsa de canicas sin orden y sin duplicados: solo importa qué hay dentro, no en qué posición. Un diccionario es como una agenda: buscas por nombre (clave) y obtienes un teléfono (valor). Aprender a elegir la colección adecuada es aprender a pensar como un programador experimentado.
5. Explicación paso a paso
5.1. Concepto de colección y panorama general
Una colección es un objeto que agrupa múltiples valores. Las cuatro colecciones fundamentales de Python se diferencian en cuatro propiedades: si son mutables (se pueden modificar después de crearlas), si están ordenadas (mantienen el orden de inserción y permiten acceso por índice), si admiten duplicados y si asocian clave y valor.
| Colección | Mutable | Ordenada | Duplicados | Clave-valor | Uso típico |
|---|---|---|---|---|---|
Lista (list) | Sí | Sí | Sí | No | Secuencia que cambia: historial, cola, pila. |
Tupla (tuple) | No | Sí | Sí | No | Registro fijo: coordenadas, datos de configuración. |
Conjunto (set) | Sí | No | No | No | Pertenencia rápida, eliminar duplicados. |
Diccionario (dict) | Sí | Sí (desde 3.7) | Claves: no; valores: sí | Sí | Búsqueda por clave: perfiles, configuraciones. |
[PYTHON] La distinción entre mutable e inmutable es central en Python. Las listas, conjuntos y diccionarios son mutables; las tuplas y las cadenas, inmutables. Esta diferencia determina qué operaciones puedes realizar y cómo se comportan las referencias (apartado 5.8). En Python 3.15 se añadefrozendict, un diccionario inmutable (apartado 5.6).
[BUENA PRÁCTICA] No elijas una colección por costumbre. Pregúntate: ¿necesito modificar los datos? ¿El orden importa? ¿Habrá duplicados? ¿Necesito buscar por una clave? Las respuestas determinan la estructura. La guía de elección se resume en el apartado 5.10.
5.2. Listas: la colección versátil
Una lista es una secuencia ordenada y mutable de elementos. Se crea con corchetes [] o con list():
frutas = ["manzana", "pera", "uva"] numeros = [10, 20, 30, 40] mixta = [1, "dos", 3.0, True] # Las listas admiten tipos heterogéneos vacia = []
Acceso por índice y segmentación: igual que en las cadenas (Módulo 5), los índices empiezan en 0 y la segmentación [inicio:fin:paso] no incluye el índice fin.
print(frutas[0]) # manzana print(frutas[-1]) # uva print(frutas[0:2]) # ['manzana', 'pera']
Modificación: a diferencia de las cadenas, puedes cambiar un elemento por índice:
frutas[1] = "plátano" print(frutas) # ['manzana', 'plátano', 'uva']
Métodos principales de lista (documentados en el tutorial oficial de estructuras de datos):
| Método | Qué hace |
|---|---|
.append(x) | Añade x al final. |
.extend(iterable) | Añade todos los elementos de iterable al final. |
.insert(i, x) | Inserta x en la posición i. |
.remove(x) | Elimina la primera aparición de x. Lanza ValueError si no existe. |
.pop([i]) | Elimina y devuelve el elemento en la posición i (por defecto, el último). |
.sort() | Ordena la lista in situ. |
.reverse() | Invierte la lista in situ. |
.index(x) | Devuelve el índice de la primera aparición de x. |
.count(x) | Cuenta cuántas veces aparece x. |
frutas.append("naranja") frutas.insert(0, "kiwi") frutas.remove("pera") ultima = frutas.pop() frutas.sort()
[PYTHON].sort()ordena in situ y devuelveNone. Si escribeslista = lista.sort(),listaseráNone. Para obtener una lista ordenada sin modificar la original, usasorted(lista). Esta distinción entre métodos que mutan y funciones que devuelven una nueva colección es una fuente constante de errores.
[ERROR HABITUAL]frutas.remove("mango")lanzaValueErrorsi"mango"no está en la lista. A diferencia de otros métodos,.remove()no devuelve un valor booleano; falla ruidosamente. Si no estás seguro de que el elemento exista, compruébalo antes conif "mango" in frutas:.
5.3. Tuplas: inmutabilidad y desempaquetado
Una tupla es una secuencia ordenada e inmutable. Se crea con paréntesis () o simplemente separando valores con comas:
coordenadas = (37.7749, -122.4194) persona = ("Ana", 25, "ana@example.com") singleton = (42,) # La coma es obligatoria para una tupla de un elemento
[ERROR HABITUAL](42)no es una tupla: es el número42entre paréntesis. Para crear una tupla de un solo elemento, necesitas la coma:(42,).
Inmutabilidad: no puedes modificar, añadir ni eliminar elementos. coordenadas[0] = 40 produce TypeError. Esta restricción es una garantía: si una tupla existe, su contenido no cambiará, lo que la hace segura para compartir y usar como clave de diccionario (las claves deben ser hashables, y la inmutabilidad es un requisito para ello).
Desempaquetado: puedes asignar los elementos de una tupla a variables individuales en una sola línea:
nombre, edad, correo = persona print(nombre) # Ana print(edad) # 25
El desempaquetado también funciona con listas y otros iterables. Es una de las características más idiomáticas de Python y se usa constantemente en la práctica.
[PYTHON] Las tuplas tienen solo dos métodos:.count(x)y.index(x). No necesitan más, porque no se modifican. Su ligereza y su inmutabilidad las hacen ligeramente más rápidas y eficientes en memoria que las listas.
5.4. Conjuntos: unicidad y operaciones matemáticas
Un conjunto (set) es una colección no ordenada de elementos únicos (sin duplicados). Se crea con llaves {} o con set():
colores = {"rojo", "verde", "azul"} numeros = set([1, 2, 2, 3, 3, 3]) # {1, 2, 3} vacio = set() # ¡No uses {} para un conjunto vacío! Eso crea un diccionario.
[ERROR HABITUAL]{}crea un diccionario vacío, no un conjunto vacío. Para un conjunto vacío, usaset().
Operaciones de conjuntos (unión, intersección, diferencia y diferencia simétrica):
| Operación | Operador | Método | Ejemplo |
|---|---|---|---|
| Unión | | | .union() | {1,2} | {2,3} → {1,2,3} |
| Intersección | & | .intersection() | {1,2} & {2,3} → {2} |
| Diferencia | - | .difference() | {1,2} - {2,3} → {1} |
| Diferencia simétrica | ^ | .symmetric_difference() | {1,2} ^ {2,3} → {1,3} |
Pertenencia rápida: x in conjunto es muy eficiente (tiempo constante promedio), mucho más que en una lista (tiempo lineal). Si tu programa hace muchas comprobaciones de pertenencia sobre una colección grande, un set es la elección correcta.
[PYTHON] Los conjuntos no mantienen el orden de inserción. No puedes acceder a sus elementos por índice (colores[0]falla). Si necesitas orden, usa una lista o una tupla. Si necesitas unicidad y orden, puedes usar un diccionario (que preserva el orden de inserción) o convertir el conjunto a lista ordenada consorted(conjunto).
5.5. Diccionarios: pares clave-valor
Un diccionario (dict) es una colección mutable que asocia claves únicas con valores. Se crea con llaves {} y pares clave: valor:
persona = { "nombre": "Ana", "edad": 25, "correo": "ana@example.com" }
Acceso: con corchetes [] o con .get():
print(persona["nombre"]) # Ana print(persona.get("edad")) # 25 print(persona.get("telefono")) # None (no lanza error) print(persona.get("telefono", "No disponible")) # Valor por defecto
[ERROR HABITUAL]persona["telefono"]lanzaKeyErrorsi la clave no existe. Usa.get()cuando no estés seguro de que la clave esté presente..get()devuelveNoneo el valor predeterminado que especifiques, sin lanzar excepción.
Métodos principales de diccionario:
| Método | Qué hace |
|---|---|
.keys() | Devuelve una vista de las claves. |
.values() | Devuelve una vista de los valores. |
.items() | Devuelve una vista de pares (clave, valor). |
.get(clave, default) | Devuelve el valor o default si la clave no existe. |
.pop(clave) | Elimina la clave y devuelve su valor. |
.update(otro) | Actualiza el diccionario con los pares de otro. |
Recorrido: iterar sobre un diccionario recorre sus claves por defecto. Para recorrer pares, usa .items():
for clave in persona: print(clave) for clave, valor in persona.items(): print(f"{clave}: {valor}")
[PYTHON] Desde Python 3.7, los diccionarios preservan el orden de inserción como garantía del lenguaje (antes era un detalle de implementación de CPython). Esto los hace útiles también cuando necesitas unicidad de claves y orden predecible.
[AMPLIACIÓN] Python 3.15 añadefrozendict, un diccionario inmutable y hashable (si sus valores también lo son). Se crea como undicty es útil para valores de configuración que no deben modificarse, como clave de otro diccionario o como valor predeterminado seguro en funciones. No lo necesitas para los ejercicios de este módulo, pero conviene que sepas que existe si lees código moderno.
5.6. Recorrido de colecciones
El bucle for del Módulo 7 es la herramienta natural para recorrer colecciones.
# Lista for fruta in frutas: print(fruta) # Lista con índice for i, fruta in enumerate(frutas): print(i, fruta) # Diccionario for clave, valor in persona.items(): print(clave, valor) # Conjunto for color in colores: print(color)
[ERROR HABITUAL] No modifiques una lista, un conjunto o un diccionario mientras lo recorres. Añadir o eliminar elementos durante la iteración puede provocar resultados impredecibles o errores. Si necesitas hacerlo, itera sobre una copia (lista.copy()) o crea una nueva colección con los elementos que quieras conservar.
5.7. Estructuras anidadas
Las colecciones pueden contener otras colecciones. Esto permite modelar datos complejos.
# Lista de diccionarios (muy común para representar registros) usuarios = [ {"nombre": "Ana", "edad": 25}, {"nombre": "Luis", "edad": 30}, ] # Diccionario de listas notas_por_alumno = { "Ana": [7, 8, 9], "Luis": [6, 10, 8], } # Acceso a estructuras anidadas print(usuarios[0]["nombre"]) # Ana print(notas_por_alumno["Ana"][1]) # 8
[BUENA PRÁCTICA] Cuando anides colecciones, documenta la estructura con un comentario o, mejor aún, con anotaciones de tipo (Módulo 18). Un diccionario de listas de diccionarios es potente, pero si no está bien documentado se vuelve difícil de mantener.
5.8. Referencias, mutabilidad y copias
Este es uno de los conceptos más importantes (y sutiles) del módulo. En el Módulo 4 viste que las variables son referencias a objetos. Con colecciones mutables, esto tiene consecuencias prácticas:
a = [1, 2, 3] b = a # b referencia el MISMO objeto que a b.append(4) print(a) # [1, 2, 3, 4] ¡a también cambió!
b = a no copia la lista: crea un segundo nombre para el mismo objeto. Si quieres una copia independiente, usa .copy() (copia superficial) o copy.deepcopy() (copia profunda):
import copy a = [1, 2, 3] b = a.copy() # Copia superficial c = copy.deepcopy(a) # Copia profunda b.append(4) print(a) # [1, 2, 3] print(b) # [1, 2, 3, 4]
Copia superficial vs. copia profunda: .copy() crea una nueva lista exterior, pero los elementos internos que sean mutables siguen compartidos. Si la lista contiene listas anidadas, modificar una sublista a través de la copia afecta también a la original. copy.deepcopy() copia recursivamente todos los niveles.
[ERROR HABITUAL] Este es el error que más tiempo hace perder a los principiantes.b = aparece una copia, pero no lo es. Siempre que necesites una colección independiente, copia explícitamente. Y si la colección contiene elementos mutables anidados, usadeepcopy().
5.9. Comprensiones (y el desempaquetado en Python 3.15)
Una comprensión es una forma concisa de crear una colección a partir de un iterable. Es una de las construcciones más idiomáticas de Python.
Comprensión de lista:
cuadrados = [x ** 2 for x in range(5)] print(cuadrados) # [0, 1, 4, 9, 16] pares = [x for x in range(10) if x % 2 == 0] print(pares) # [0, 2, 4, 6, 8]
Comprensión de conjunto:
unicos = {x % 3 for x in range(10)} print(unicos) # {0, 1, 2}
Comprensión de diccionario:
longitudes = {palabra: len(palabra) for palabra in ["hola", "mundo"]} print(longitudes) # {'hola': 4, 'mundo': 5}
[PYTHON] Las comprensiones son más eficientes y, una vez acostumbrado, más legibles que un bucle conappend(). Sin embargo, si la lógica es compleja (múltiples condiciones, efectos secundarios), un bucle explícito es preferible. La claridad siempre gana.
[AMPLIACIÓN] Python 3.15 introduce el desempaquetado en comprensiones (PEP 798): puedes usar*en una comprensión de lista o conjunto, y**en una de diccionario, para aplanar o fusionar colecciones directamente.
listas = [[1, 2], [3, 4], [5]] plana = [*L for L in listas] print(plana) # [1, 2, 3, 4, 5] dicts = [{'a': 1}, {'b': 2}, {'a': 3}] fusionado = {**d for d in dicts} print(fusionado) # {'a': 3, 'b': 2}
Esta sintaxis es nueva y opcional; no la necesitas para los ejercicios básicos, pero es útil para procesar datos.
5.10. Selección de la estructura apropiada
| Necesitas… | Usa… | Motivo |
|---|---|---|
| Una secuencia ordenada que cambie | Lista | Mutabilidad, orden, duplicados. |
| Un registro fijo que no cambie | Tupla | Inmutabilidad, seguridad, uso como clave. |
| Eliminar duplicados o comprobar pertenencia rápida | Conjunto | Unicidad, in eficiente. |
| Asociar claves con valores y buscar por clave | Diccionario | Acceso O(1) por clave, orden de inserción. |
[BUENA PRÁCTICA] Si dudas entre lista y tupla, pregúntate si el contenido debe cambiar después de crearlo. Si la respuesta es no, una tupla comunica esa intención al lector y evita modificaciones accidentales. Si dudas entre lista y conjunto, pregúntate si el orden importa y si puede haber duplicados.
6. Ejemplos comentados
Ejemplo 1: Lista de notas y cálculo de la media.
notas = [7, 8, 6, 9, 10] notas.append(5) notas.remove(6) notas.sort() total = sum(notas) media = total / len(notas) print(f"Notas ordenadas: {notas}") print(f"Media: {media:.2f}")
Seguimiento: append(5) añade al final; remove(6) elimina el 6; sort() ordena. sum() y len() son funciones incorporadas que funcionan con cualquier iterable numérico.
Ejemplo 2: Diccionario de un usuario.
usuario = { "nombre": "Ana", "edad": 25, "intereses": ["Python", "ajedrez", "senderismo"] } print(usuario["nombre"]) print(usuario["intereses"][0]) # Python usuario["edad"] = 26 usuario["ciudad"] = "Sevilla" for clave, valor in usuario.items(): print(f"{clave}: {valor}")
Seguimiento: Se accede a una lista dentro de un diccionario con doble índice. Se modifica un valor existente y se añade uno nuevo. .items() permite recorrer ambos.
Ejemplo 3: Conjunto para eliminar duplicados.
numeros = [1, 2, 2, 3, 3, 3, 4] unicos = set(numeros) print(unicos) # {1, 2, 3, 4} print(2 in unicos) # True
Seguimiento: set(numeros) convierte la lista en un conjunto, eliminando duplicados. La pertenencia es inmediata.
7. Seguimiento de la ejecución
Cuando ejecutas b = a sobre una lista, Python no copia los elementos: asigna a b la misma referencia que a. Ambas variables apuntan al mismo objeto en memoria. Por eso b.append(4) se refleja en a.
Cuando ejecutas b = a.copy(), Python crea un nuevo objeto lista y copia las referencias a los elementos. Si los elementos son inmutables (números, cadenas), la copia es completamente independiente. Si los elementos son mutables (listas anidadas), ambas listas comparten esos elementos internos: modificar una sublista a través de b también la modifica en a. Para una independencia total, copy.deepcopy() copia recursivamente todos los niveles.
8. Errores habituales
| Error | Causa | Cómo diagnosticarlo |
|---|---|---|
b = a no copia | Asignación de referencia, no de valor. | Usa .copy() o deepcopy(). |
lista = lista.sort() deja None | .sort() muta in situ y devuelve None. | Usa sorted(lista) si quieres una nueva lista. |
{} para conjunto vacío | {} crea un diccionario. | Usa set() para un conjunto vacío. |
(42) no es tupla | Falta la coma. | Escribe (42,). |
KeyError al acceder a un diccionario | La clave no existe. | Usa .get() o comprueba con in. |
ValueError en .remove() | El elemento no está en la lista. | Comprueba con in antes de eliminar. |
| Modificar una colección mientras se itera | Comportamiento impredecible. | Itera sobre una copia o crea una nueva colección. |
| Copia superficial de estructuras anidadas | Los elementos internos se comparten. | Usa copy.deepcopy() para independencia total. |
[ERROR HABITUAL] El error deb = aes especialmente peligroso porque no produce ningún mensaje: el programa funciona, pero los datos se corrompen silenciosamente. Siempre que necesites una copia independiente, sé explícito.
9. Particularidades de Python frente a otros lenguajes
- Listas como arrays dinámicos: en C o Java, los arrays tienen tamaño fijo; en Python, las listas crecen y se encogen dinámicamente. Esto simplifica el código, pero oculta la gestión de memoria.
- Tuplas como registros ligeros: en otros lenguajes, un registro fijo requiere una struct o una clase. En Python, una tupla es una forma inmediata de agrupar valores heterogéneos sin definir un tipo.
- Conjuntos nativos: en C no existen; en Java, HashSet es una clase de la biblioteca estándar. En Python, set es un tipo incorporado con sintaxis literal ({}).
- Diccionarios con orden de inserción garantizado: desde Python 3.7, es una garantía del lenguaje. En Java, HashMap no garantiza orden; LinkedHashMap sí, pero es una elección explícita.
- Comprensiones: son una sintaxis propia de Python (aunque lenguajes como JavaScript tienen map/filter). Permiten crear colecciones en una sola expresión, de forma muy legible.
10. Buenas prácticas
Incorrecto (copia accidental y modificación durante la iteración):
a = [1, 2, 3] b = a b.append(4) # a también cambia for x in a: if x == 2: a.remove(x) # Comportamiento impredecible
Mejor:
a = [1, 2, 3] b = a.copy() b.append(4) # a no cambia a = [x for x in a if x != 2] # Nueva lista sin el 2
[BUENA PRÁCTICA] Usa comprensiones para transformar o filtrar colecciones de forma concisa. Usa.copy()odeepcopy()cuando necesites independencia. No modifiques una colección mientras la recorres. Y elige la colección según el problema, no por costumbre.
11. Windows y Linux
Las colecciones son idénticas en Windows y Linux. La sintaxis, los métodos y el comportamiento son los mismos. La única diferencia potencial es el rendimiento en casos extremos, pero para el nivel de este curso es irrelevante.
[WINDOWS / LINUX] Si tu programa lee datos de un archivo (Módulo 13) y los procesa con colecciones, recuerda que la codificación UTF-8 está garantizada por defecto en Python 3.15, lo que evita problemas con tildes y caracteres especiales en ambos sistemas.
12. Ejercicios guiados
Ejercicio guiado 1: Lista de compras.
Crea una lista con tres productos. Añade uno más con .append(), elimina el segundo con .remove(), ordena la lista y muéstrala.
Ejercicio guiado 2: Diccionario de contacto.
Crea un diccionario con nombre, telefono y email. Accede al teléfono con [] y a un campo inexistente con .get(). Añade una nueva clave ciudad y recorre el diccionario con .items().
Ejercicio guiado 3: Conjunto de etiquetas.
Dada la lista ["python", "datos", "python", "web", "datos"], conviértela en un conjunto para obtener las etiquetas únicas. Muestra el conjunto y comprueba si "web" está presente.
13. Ejercicios autónomos
1. Predicción: ¿Qué muestra cada fragmento? Razona antes de ejecutar.
```python a = [1, 2, 3] b = a b.append(4) print(a) ``` ```python a = [1, 2, 3] b = a.copy() b.append(4) print(a) ```
2. Lista de notas: Pide cinco notas al usuario, guárdalas en una lista, calcula la media y muestra la nota más alta y la más baja. Pista: max() y min() funcionan con listas.
3. Diccionario de frecuencias: Pide una frase y cuenta cuántas veces aparece cada palabra. Usa un diccionario donde las claves sean las palabras y los valores los conteos. Pista: palabras = frase.split() y luego recorre con un bucle; usa .get(palabra, 0) + 1.
4. Conjuntos: Dadas dos listas de nombres, obtén los nombres que aparecen en ambas (intersección) y los que aparecen en al menos una (unión).
5. Reto opcional: Investiga la diferencia entre .copy() y copy.deepcopy() con una lista anidada. Crea a = [[1, 2], [3, 4]], haz una copia superficial y una profunda, modifica un elemento interno de la copia y observa qué ocurre en a.
14. Soluciones razonadas
Solución al ejercicio guiado 1:
compras = ["pan", "leche", "huevos"] compras.append("café") compras.remove("leche") compras.sort() print(compras) # ['café', 'huevos', 'pan']
sort() ordena alfabéticamente. remove() elimina la primera aparición.
Solución al ejercicio guiado 2:
contacto = {"nombre": "Ana", "telefono": "123456789", "email": "ana@example.com"} print(contacto["telefono"]) print(contacto.get("direccion", "No disponible")) contacto["ciudad"] = "Sevilla" for clave, valor in contacto.items(): print(f"{clave}: {valor}")
.get() evita KeyError. La asignación añade una nueva clave.
Solución al ejercicio guiado 3:
etiquetas = ["python", "datos", "python", "web", "datos"] unicas = set(etiquetas) print(unicas) # {'python', 'datos', 'web'} (el orden puede variar) print("web" in unicas) # True
set() elimina duplicados automáticamente.
Solución al ejercicio 1 (predicción):
- Primer fragmento: [1, 2, 3, 4] porque b = a comparte la referencia.
- Segundo fragmento: [1, 2, 3] porque .copy() crea una lista independiente.
Solución al ejercicio 2 (notas):
notas = [] for _ in range(5): nota = float(input("Introduce una nota: ")) notas.append(nota) media = sum(notas) / len(notas) print(f"Media: {media:.2f}") print(f"Máxima: {max(notas)}") print(f"Mínima: {min(notas)}")
max() y min() son funciones incorporadas que aceptan cualquier iterable.
Solución al ejercicio 3 (frecuencias):
frase = input("Introduce una frase: ") frecuencias = {} for palabra in frase.split(): frecuencias[palabra] = frecuencias.get(palabra, 0) + 1 for palabra, conteo in frecuencias.items(): print(f"{palabra}: {conteo}")
.get(palabra, 0) devuelve 0 si la palabra no está aún en el diccionario, evitando KeyError.
Solución al ejercicio 5 (reto opcional, orientativa):
import copy a = [[1, 2], [3, 4]] b = a.copy() c = copy.deepcopy(a) b[0][0] = 99 print(a) # [[99, 2], [3, 4]] (a cambió) print(b) # [[99, 2], [3, 4]] (misma sublista) c[0][0] = 77 print(a) # [[99, 2], [3, 4]] (a NO cambió) print(c) # [[77, 2], [3, 4]] (independiente)
.copy() comparte las sublistas internas; deepcopy() las copia también.
15. Resumen
- Las colecciones agrupan múltiples valores. Las cuatro fundamentales son listas, tuplas, conjuntos y diccionarios.
- Listas: ordenadas, mutables, admiten duplicados. Métodos clave: .append(), .remove(), .sort(), .pop().
- Tuplas: ordenadas, inmutables, admiten duplicados. Útiles para registros fijos y como claves de diccionario. Se desempaquetan con a, b = tupla.
- Conjuntos: no ordenados, mutables, sin duplicados. Operaciones: |, &, -, ^. Pertenencia muy rápida.
- Diccionarios: pares clave-valor, mutables, orden de inserción garantizado. Acceso con [] o .get(); recorrido con .items().
- Las referencias y la mutabilidad exigen copias explícitas (.copy() o deepcopy()) cuando se necesita independencia.
- Las comprensiones crean colecciones en una expresión. Python 3.15 añade el desempaquetado con * y ** en comprensiones.
- Elige la colección según el problema: orden, mutabilidad, unicidad y acceso por clave.
16. Autoevaluación
1. ¿Qué diferencia hay entre una lista y una tupla? ¿Cuándo usarías cada una?
2. ¿Por qué {} no crea un conjunto vacío? ¿Qué crea?
3. ¿Qué hace .get() y por qué es preferible a [] en algunos casos?
4. Explica con tus palabras la diferencia entre b = a, b = a.copy() y b = copy.deepcopy(a).
5. Reto: Sin ejecutar, predice el resultado de {x for x in [1, 2, 2, 3] if x > 1}. Luego compruébalo y explica qué tipo de colección se ha creado.
