Estructuras de Datos en Python: Listas, Tuplas, Diccionarios y Sets
Introduccion: por que necesitamos colecciones de datos
Bienvenido a la parte 5 de 10 de nuestro curso de Python para principiantes. Hasta ahora hemos trabajado con variables que guardan un solo valor: un numero, un texto, un booleano. Pero en la vida real, casi siempre necesitamos manejar grupos de datos.
Piensa en una lista de compras, los contactos de tu telefono, o las calificaciones de un estudiante. Todos son colecciones de datos. Python tiene 4 estructuras principales para organizar datos: listas, tuplas, diccionarios y sets. En este articulo aprenderemos cada una con ejemplos practicos.

Listas: tu primera coleccion
Una lista es una coleccion ordenada de elementos que puedes modificar. Es probablemente la estructura de datos que mas usaras en Python. Se crean con corchetes [].
Crear una lista
1# Lista de frutas
2frutas = ["manzana", "platano", "naranja"]
3print(frutas) # ['manzana', 'platano', 'naranja']
4
5# Lista de numeros
6numeros = [10, 20, 30, 40, 50]
7print(numeros) # [10, 20, 30, 40, 50]
8
9# Lista mixta (diferentes tipos de datos)
10mezcla = ["hola", 42, True, 3.14]
11print(mezcla) # ['hola', 42, True, 3.14]
12
13# Lista vacia
14vacia = []
15print(vacia) # []
Acceder a elementos
Cada elemento tiene una posicion (indice) que empieza en 0, no en 1. Esto es muy importante recordarlo.
1frutas = ["manzana", "platano", "naranja", "uva"]
2
3# Acceder por indice (empieza en 0)
4print(frutas[0]) # manzana (el primero)
5print(frutas[1]) # platano (el segundo)
6print(frutas[3]) # uva (el cuarto)
7
8# Indices negativos (desde el final)
9print(frutas[-1]) # uva (el ultimo)
10print(frutas[-2]) # naranja (el penultimo)
lista[-1] siempre te da el ultimo elemento sin necesidad de saber cuantos elementos tiene la lista.
Modificar elementos
1frutas = ["manzana", "platano", "naranja"]
2
3# Cambiar un elemento
4frutas[1] = "fresa"
5print(frutas) # ['manzana', 'fresa', 'naranja']
6
7# Agregar al final
8frutas.append("uva")
9print(frutas) # ['manzana', 'fresa', 'naranja', 'uva']
10
11# Eliminar un elemento por valor
12frutas.remove("fresa")
13print(frutas) # ['manzana', 'naranja', 'uva']
14
15# Eliminar por indice
16del frutas[0]
17print(frutas) # ['naranja', 'uva']
Rebanadas (slicing)
Puedes obtener una parte de la lista usando rebanadas:
1numeros = [10, 20, 30, 40, 50, 60]
2
3print(numeros[1:4]) # [20, 30, 40] (del indice 1 al 3)
4print(numeros[:3]) # [10, 20, 30] (del inicio al indice 2)
5print(numeros[3:]) # [40, 50, 60] (del indice 3 al final)
6print(numeros[::2]) # [10, 30, 50] (de 2 en 2)
Metodos utiles de listas
Las listas tienen muchos metodos que te facilitan la vida. Aqui los mas importantes:
1numeros = [3, 1, 4, 1, 5, 9, 2, 6]
2
3# append() - agregar al final
4numeros.append(7)
5print(numeros) # [3, 1, 4, 1, 5, 9, 2, 6, 7]
6
7# insert() - insertar en una posicion especifica
8numeros.insert(0, 99) # insertar 99 en la posicion 0
9print(numeros) # [99, 3, 1, 4, 1, 5, 9, 2, 6, 7]
10
11# remove() - eliminar la primera aparicion de un valor
12numeros.remove(1) # elimina el primer 1
13print(numeros) # [99, 3, 4, 1, 5, 9, 2, 6, 7]
14
15# pop() - eliminar y devolver el ultimo elemento (o el de un indice)
16ultimo = numeros.pop()
17print(ultimo) # 7
18print(numeros) # [99, 3, 4, 1, 5, 9, 2, 6]
19
20segundo = numeros.pop(1) # eliminar el indice 1
21print(segundo) # 3
22
23# sort() - ordenar la lista
24numeros.sort()
25print(numeros) # [1, 2, 4, 5, 6, 9, 99]
26
27# reverse() - invertir el orden
28numeros.reverse()
29print(numeros) # [99, 9, 6, 5, 4, 2, 1]
30
31# len() - saber cuantos elementos tiene
32print(len(numeros)) # 7
33
34# in - verificar si un elemento existe
35print(5 in numeros) # True
36print(100 in numeros) # False
sort() modifica la lista original. Si quieres obtener una copia ordenada sin modificar la original, usa sorted(lista).
Tuplas: listas que no se pueden cambiar
Una tupla es muy parecida a una lista, pero con una diferencia fundamental: no se puede modificar despues de crearla. Esto se llama inmutabilidad. Se crean con parentesis ().
1# Crear una tupla
2coordenadas = (10, 20)
3print(coordenadas) # (10, 20)
4print(coordenadas[0]) # 10
5print(coordenadas[1]) # 20
6
7# Tupla con varios elementos
8colores = ("rojo", "verde", "azul")
9print(colores[1]) # verde
10
11# Intentar modificar una tupla da error
12# colores[0] = "amarillo" # TypeError: 'tuple' object does not support item assignment
Cuando usar tuplas en lugar de listas
- Datos que no deben cambiar: coordenadas geograficas, fechas, configuraciones fijas
- Claves de diccionario: las tuplas pueden ser claves, las listas no
- Funciones que retornan multiples valores: Python usa tuplas automaticamente
- Rendimiento: las tuplas son ligeramente mas rapidas que las listas
1# Funcion que retorna multiples valores (como tupla)
2def obtener_nombre_completo():
3 return "Juan", "Garcia" # Python crea una tupla automaticamente
4
5nombre, apellido = obtener_nombre_completo() # desempaquetado
6print(nombre) # Juan
7print(apellido) # Garcia
8
9# Tupla como clave de diccionario
10ubicaciones = {
11 (19.43, -99.13): "Ciudad de Mexico",
12 (40.71, -74.00): "Nueva York"
13}
14print(ubicaciones[(19.43, -99.13)]) # Ciudad de Mexico
mi_tupla = (42,). Sin la coma, Python lo interpreta como un numero entre parentesis: (42) es simplemente 42.
Diccionarios: pares clave-valor
Un diccionario es una coleccion que almacena datos en pares clave: valor. Es como un diccionario real: buscas una palabra (clave) y encuentras su definicion (valor). Se crean con llaves {}.
Crear y acceder a diccionarios
1# Crear un diccionario
2persona = {
3 "nombre": "Ana",
4 "edad": 25,
5 "ciudad": "Guadalajara"
6}
7
8# Acceder a valores por clave
9print(persona["nombre"]) # Ana
10print(persona["edad"]) # 25
11
12# Acceder con get() (mas seguro, no da error si la clave no existe)
13print(persona.get("nombre")) # Ana
14print(persona.get("telefono")) # None (no existe, pero no da error)
15print(persona.get("telefono", "No disponible")) # "No disponible" (valor por defecto)
Agregar y modificar
1persona = {"nombre": "Ana", "edad": 25}
2
3# Agregar un nuevo par clave-valor
4persona["email"] = "[email protected]"
5print(persona)
6# {'nombre': 'Ana', 'edad': 25, 'email': '[email protected]'}
7
8# Modificar un valor existente
9persona["edad"] = 26
10print(persona["edad"]) # 26
11
12# Eliminar un par clave-valor
13del persona["email"]
14print(persona) # {'nombre': 'Ana', 'edad': 26}
Recorrer un diccionario
1persona = {"nombre": "Ana", "edad": 25, "ciudad": "Guadalajara"}
2
3# Recorrer claves
4for clave in persona:
5 print(clave) # nombre, edad, ciudad
6
7# Recorrer valores
8for valor in persona.values():
9 print(valor) # Ana, 25, Guadalajara
10
11# Recorrer claves y valores al mismo tiempo
12for clave, valor in persona.items():
13 print(f"{clave}: {valor}")
14# nombre: Ana
15# edad: 25
16# ciudad: Guadalajara
Metodos de diccionarios
Los diccionarios tienen metodos muy utiles para trabajar con sus datos:
1persona = {"nombre": "Ana", "edad": 25, "ciudad": "Guadalajara"}
2
3# keys() - obtener todas las claves
4print(persona.keys()) # dict_keys(['nombre', 'edad', 'ciudad'])
5
6# values() - obtener todos los valores
7print(persona.values()) # dict_values(['Ana', 25, 'Guadalajara'])
8
9# items() - obtener pares clave-valor como tuplas
10print(persona.items())
11# dict_items([('nombre', 'Ana'), ('edad', 25), ('ciudad', 'Guadalajara')])
12
13# get() - obtener valor con valor por defecto
14telefono = persona.get("telefono", "No registrado")
15print(telefono) # No registrado
16
17# update() - actualizar con otro diccionario
18persona.update({"edad": 26, "profesion": "ingeniera"})
19print(persona)
20# {'nombre': 'Ana', 'edad': 26, 'ciudad': 'Guadalajara', 'profesion': 'ingeniera'}
21
22# pop() - eliminar y devolver un valor
23ciudad = persona.pop("ciudad")
24print(ciudad) # Guadalajara
25print(persona) # {'nombre': 'Ana', 'edad': 26, 'profesion': 'ingeniera'}
26
27# Verificar si una clave existe
28print("nombre" in persona) # True
29print("telefono" in persona) # False
get() en lugar de diccionario["clave"] cuando no estes seguro de que la clave existe. Asi evitas errores KeyError.
Sets (conjuntos): colecciones sin duplicados
Un set (conjunto) es una coleccion desordenada de elementos unicos. No permite duplicados y no tiene un orden definido. Se crean con llaves {} o con set().
Crear y usar sets
1# Crear un set
2frutas = {"manzana", "platano", "naranja", "manzana"}
3print(frutas) # {'manzana', 'platano', 'naranja'} (sin duplicados!)
4
5# Crear set desde una lista (elimina duplicados)
6numeros = [1, 2, 2, 3, 3, 3, 4]
7unicos = set(numeros)
8print(unicos) # {1, 2, 3, 4}
9
10# Agregar elementos
11frutas.add("uva")
12print(frutas) # {'manzana', 'platano', 'naranja', 'uva'}
13
14# Eliminar elementos
15frutas.discard("platano") # no da error si no existe
16print(frutas) # {'manzana', 'naranja', 'uva'}
Operaciones de conjuntos
Los sets son especialmente utiles para operaciones matematicas de conjuntos:
1python_devs = {"Ana", "Luis", "Maria", "Carlos"}
2java_devs = {"Luis", "Pedro", "Maria", "Sofia"}
3
4# Union: todos los elementos de ambos sets
5todos = python_devs | java_devs # o python_devs.union(java_devs)
6print(todos) # {'Ana', 'Luis', 'Maria', 'Carlos', 'Pedro', 'Sofia'}
7
8# Interseccion: elementos que estan en ambos
9ambos = python_devs & java_devs # o python_devs.intersection(java_devs)
10print(ambos) # {'Luis', 'Maria'}
11
12# Diferencia: elementos que estan en uno pero no en el otro
13solo_python = python_devs - java_devs # o python_devs.difference(java_devs)
14print(solo_python) # {'Ana', 'Carlos'}
15
16# Diferencia simetrica: elementos que estan en uno u otro, pero no en ambos
17exclusivos = python_devs ^ java_devs
18print(exclusivos) # {'Ana', 'Carlos', 'Pedro', 'Sofia'}
set(), no {}. Las llaves vacias {} crean un diccionario vacio, no un set.
Tabla comparativa de las 4 estructuras
Esta tabla resume las diferencias principales entre las 4 estructuras de datos:
| Caracteristica | Lista [] |
Tupla () |
Diccionario {} |
Set {} |
|---|---|---|---|---|
| Mutable | Si | No | Si | Si |
| Ordenada | Si | Si | Si (desde Python 3.7) | No |
| Permite duplicados | Si | Si | No (claves unicas) | No |
| Acceso por indice | Si | Si | Por clave | No |
| Uso tipico | Colecciones modificables | Datos constantes | Mapeo clave-valor | Elementos unicos |
| Ejemplo | [1, 2, 3] |
(1, 2, 3) |
{"a": 1} |
{1, 2, 3} |
List comprehensions: crear listas de forma rapida
Las list comprehensions son una forma elegante y rapida de crear listas en una sola linea. Es como un atajo para combinar un for con un append.
Sintaxis basica
1# Forma tradicional
2cuadrados = []
3for n in range(1, 6):
4 cuadrados.append(n ** 2)
5print(cuadrados) # [1, 4, 9, 16, 25]
6
7# Con list comprehension (una sola linea!)
8cuadrados = [n ** 2 for n in range(1, 6)]
9print(cuadrados) # [1, 4, 9, 16, 25]
Con condicion (filtro)
1# Solo numeros pares
2pares = [n for n in range(1, 11) if n % 2 == 0]
3print(pares) # [2, 4, 6, 8, 10]
4
5# Palabras que empiezan con 'p'
6palabras = ["python", "java", "php", "rust", "perl"]
7con_p = [p for p in palabras if p.startswith("p")]
8print(con_p) # ['python', 'php', 'perl']
9
10# Convertir a mayusculas
11mayusculas = [p.upper() for p in palabras]
12print(mayusculas) # ['PYTHON', 'JAVA', 'PHP', 'RUST', 'PERL']
for normal es mas legible.
Ejemplo practico: agenda de contactos
Vamos a crear una agenda de contactos usando diccionarios para poner en practica todo lo aprendido:
1# Agenda de contactos usando una lista de diccionarios
2agenda = []
3
4def agregar_contacto(nombre, telefono, email=""):
5 """Agrega un nuevo contacto a la agenda."""
6 contacto = {
7 "nombre": nombre,
8 "telefono": telefono,
9 "email": email
10 }
11 agenda.append(contacto)
12 print(f"Contacto '{nombre}' agregado correctamente.")
13
14def buscar_contacto(nombre):
15 """Busca un contacto por nombre."""
16 resultados = [c for c in agenda if nombre.lower() in c["nombre"].lower()]
17 if resultados:
18 for c in resultados:
19 print(f" Nombre: {c['nombre']}")
20 print(f" Telefono: {c['telefono']}")
21 print(f" Email: {c['email'] or 'No registrado'}")
22 print(" ---")
23 else:
24 print(f" No se encontraron contactos con '{nombre}'.")
25
26def mostrar_agenda():
27 """Muestra todos los contactos."""
28 if not agenda:
29 print(" La agenda esta vacia.")
30 return
31 print(f" Total de contactos: {len(agenda)}")
32 for i, c in enumerate(agenda, 1):
33 print(f" {i}. {c['nombre']} - {c['telefono']}")
34
35def eliminar_contacto(nombre):
36 """Elimina un contacto por nombre exacto."""
37 for c in agenda:
38 if c["nombre"].lower() == nombre.lower():
39 agenda.remove(c)
40 print(f" Contacto '{nombre}' eliminado.")
41 return
42 print(f" Contacto '{nombre}' no encontrado.")
43
44# Probemos la agenda
45agregar_contacto("Ana Lopez", "555-1234", "[email protected]")
46agregar_contacto("Carlos Ruiz", "555-5678")
47agregar_contacto("Ana Maria", "555-9999", "[email protected]")
48
49print("\n--- Buscar 'ana' ---")
50buscar_contacto("ana")
51
52print("\n--- Agenda completa ---")
53mostrar_agenda()
54
55print("\n--- Eliminar 'Carlos Ruiz' ---")
56eliminar_contacto("Carlos Ruiz")
57
58print("\n--- Agenda actualizada ---")
59mostrar_agenda()
Este ejemplo combina listas (para guardar los contactos), diccionarios (para representar cada contacto) y list comprehensions (para buscar contactos). Es un patron muy comun en Python.
Resumen y proximo articulo
En este articulo aprendimos las 4 estructuras de datos fundamentales de Python:
- Listas: colecciones ordenadas y modificables, ideales para la mayoria de los casos
- Tuplas: como listas pero inmutables, perfectas para datos que no deben cambiar
- Diccionarios: pares clave-valor, ideales para representar objetos con propiedades
- Sets: colecciones sin duplicados, utiles para operaciones de conjuntos
Tambien aprendimos list comprehensions para crear listas de forma rapida y elegante, y construimos una agenda de contactos como ejemplo practico.
Comments
Sign in to leave a comment
No comments yet. Be the first!