En esta página
Listas y tuplas
Listas en Python
Las listas son la estructura de datos más versátil de Python. Son colecciones ordenadas y mutables que pueden contener elementos de cualquier tipo, incluso mezclados:
# Crear listas
vacía = []
numeros = [1, 2, 3, 4, 5]
textos = ["Python", "JavaScript", "Rust"]
mixta = [1, "hola", True, 3.14, None]
anidada = [[1, 2], [3, 4], [5, 6]]
# list() — crear desde otros iterables
desde_rango = list(range(1, 6)) # [1, 2, 3, 4, 5]
desde_string = list("Python") # ['P', 'y', 't', 'h', 'o', 'n']
desde_tupla = list((1, 2, 3)) # [1, 2, 3]
# Longitud
print(len(numeros)) # 5
print(len(vacía)) # 0Indexación
Python usa indexación basada en cero. Los índices negativos cuentan desde el final:
frutas = ["manzana", "pera", "uva", "naranja", "kiwi"]
# Índices positivos
print(frutas[0]) # "manzana"
print(frutas[1]) # "pera"
print(frutas[4]) # "kiwi"
# Índices negativos
print(frutas[-1]) # "kiwi" — último
print(frutas[-2]) # "naranja" — penúltimo
print(frutas[-5]) # "manzana" — primero desde el final
# Acceso a listas anidadas
matriz = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(matriz[1][2]) # 6 — fila 1, columna 2
print(matriz[0][0]) # 1 — primera fila, primera columnaSlicing (rebanado)
El slicing permite extraer sublistas con la sintaxis lista[inicio:fin:paso]. El índice fin es exclusivo:
letras = ["a", "b", "c", "d", "e", "f", "g"]
# Casos básicos
print(letras[1:4]) # ['b', 'c', 'd'] — índices 1, 2, 3
print(letras[:3]) # ['a', 'b', 'c'] — desde el inicio hasta 3 (exclusivo)
print(letras[4:]) # ['e', 'f', 'g'] — desde índice 4 hasta el final
print(letras[:]) # ['a', 'b', 'c', 'd', 'e', 'f', 'g'] — copia completa
print(letras[-3:]) # ['e', 'f', 'g'] — últimos 3 elementos
# Con paso
print(letras[::2]) # ['a', 'c', 'e', 'g'] — cada segundo elemento
print(letras[1::2]) # ['b', 'd', 'f'] — pares (índices impares)
print(letras[::-1]) # ['g', 'f', 'e', 'd', 'c', 'b', 'a'] — invertida
print(letras[6:1:-2]) # ['g', 'e', 'c'] — hacia atrás de 2 en 2
# Asignación mediante slicing
numeros = [0, 1, 2, 3, 4, 5]
numeros[1:4] = [10, 20] # Reemplaza 3 elementos con 2
print(numeros) # [0, 10, 20, 4, 5]
numeros[2:2] = [100, 200] # Inserción sin reemplazar
print(numeros) # [0, 10, 100, 200, 20, 4, 5]Métodos de lista
Las listas tienen métodos que permiten modificarlas. Es importante entender si el método modifica la lista in-place o devuelve un nuevo objeto:
tareas = ["estudiar", "programar", "descansar"]
# append() — agrega un elemento al final (in-place, devuelve None)
tareas.append("hacer ejercicio")
print(tareas) # ['estudiar', 'programar', 'descansar', 'hacer ejercicio']
# extend() — agrega múltiples elementos al final (in-place)
tareas.extend(["leer", "meditar"])
print(tareas)
# insert() — inserta en una posición específica (in-place)
tareas.insert(1, "tomar café") # Inserta en índice 1
print(tareas[0:3]) # ['estudiar', 'tomar café', 'programar']
# remove() — elimina la primera ocurrencia de un valor (in-place)
tareas.remove("tomar café")
# pop() — elimina y devuelve un elemento (in-place)
ultima = tareas.pop() # Elimina el último
print(ultima) # 'meditar'
segunda = tareas.pop(1) # Elimina por índice
print(segunda) # 'programar'
# clear() — vacía la lista (in-place)
temp = [1, 2, 3]
temp.clear()
print(temp) # []
# index() — devuelve el índice de la primera ocurrencia
nums = [10, 20, 30, 20, 40]
print(nums.index(20)) # 1 — primer 20
print(nums.index(20, 2)) # 3 — busca desde índice 2
# count() — cuenta ocurrencias
print(nums.count(20)) # 2
# sort() — ordena in-place (no devuelve la lista)
nombres = ["Carlos", "Ana", "Bruno", "Diana"]
nombres.sort()
print(nombres) # ['Ana', 'Bruno', 'Carlos', 'Diana']
nombres.sort(key=str.lower, reverse=True) # Con criterio personalizado
print(nombres) # ['Diana', 'Carlos', 'Bruno', 'Ana']
# sorted() — devuelve nueva lista ordenada (no modifica la original)
original = [3, 1, 4, 1, 5, 9, 2, 6]
ordenada = sorted(original)
print(original) # [3, 1, 4, 1, 5, 9, 2, 6] — sin cambios
print(ordenada) # [1, 1, 2, 3, 4, 5, 6, 9]
# reverse() — invierte in-place
nombres.reverse()
print(nombres) # ['Ana', 'Bruno', 'Carlos', 'Diana'] (ya estaba ordenada al revés)
# copy() — copia superficial
original = [1, 2, 3]
copia = original.copy() # Equivalente a original[:]
copia.append(4)
print(original) # [1, 2, 3] — no afectado
print(copia) # [1, 2, 3, 4]Tuplas: inmutabilidad por diseño
Las tuplas son colecciones ordenadas e inmutables. Se crean con paréntesis o simplemente con comas:
# Crear tuplas
vacía = ()
un_elemento = (42,) # La coma es necesaria para un solo elemento
coordenadas = (3.5, 7.2)
rgb = (255, 128, 0)
punto_3d = (1, 2, 3)
# Sin paréntesis (empaquetado automático)
dimensiones = 1920, 1080
print(type(dimensiones)) # <class 'tuple'>
# tuple() — convertir desde iterables
desde_lista = tuple([1, 2, 3]) # (1, 2, 3)
desde_string = tuple("Python") # ('P', 'y', 't', 'h', 'o', 'n')
# Inmutabilidad
coords = (10, 20)
# coords[0] = 5 # TypeError: 'tuple' object does not support item assignment
# Pero si contiene mutables, esos sí se pueden modificar
tupla_con_lista = ([1, 2], [3, 4])
tupla_con_lista[0].append(100) # ¡Esto sí funciona!
print(tupla_con_lista) # ([1, 2, 100], [3, 4])Desempaquetado de tuplas y listas
El desempaquetado es una de las características más elegantes de Python:
# Desempaquetado básico
punto = (3, 7)
x, y = punto
print(f"x={x}, y={y}") # x=3, y=7
# Desempaquetado con asterisco
primero, *resto = [1, 2, 3, 4, 5]
print(primero) # 1
print(resto) # [2, 3, 4, 5]
*inicio, ultimo = [1, 2, 3, 4, 5]
print(inicio) # [1, 2, 3, 4]
print(ultimo) # 5
primero, *medio, ultimo = [1, 2, 3, 4, 5]
print(primero) # 1
print(medio) # [2, 3, 4]
print(ultimo) # 5
# Intercambio de variables (sin variable temporal)
a, b = 10, 20
a, b = b, a
print(a, b) # 20 10
# Desempaquetado anidado
matriz = [(1, 'a'), (2, 'b'), (3, 'c')]
for num, letra in matriz:
print(f"{num} → {letra}")
# Ignorar valores con _
datos = ("Ana", 28, "Madrid", "[email protected]")
nombre, _, ciudad, _ = datos
print(nombre, ciudad) # Ana Madridenumerate() — índice y valor simultáneamente
lenguajes = ["Python", "JavaScript", "Rust", "Go", "TypeScript"]
# Forma incorrecta (anti-patrón)
for i in range(len(lenguajes)):
print(f"{i}: {lenguajes[i]}")
# Forma Pythónica — con enumerate()
for i, lenguaje in enumerate(lenguajes):
print(f"{i}: {lenguaje}")
# Con inicio personalizado
for pos, lenguaje in enumerate(lenguajes, start=1):
print(f"{pos}. {lenguaje}")
# 1. Python
# 2. JavaScript
# 3. Rust
# 4. Go
# 5. TypeScript
# enumerate devuelve pares (índice, valor) como tuplas
pares = list(enumerate(lenguajes))
print(pares) # [(0, 'Python'), (1, 'JavaScript'), ...]zip() — iterar múltiples secuencias en paralelo
nombres = ["Ana", "Bruno", "Carmen", "Diego"]
edades = [25, 30, 28, 35]
ciudades = ["Madrid", "Barcelona", "Sevilla", "Valencia"]
# zip() crea pares de elementos
for nombre, edad, ciudad in zip(nombres, edades, ciudades):
print(f"{nombre} ({edad}) — {ciudad}")
# zip se detiene en la secuencia más corta
a = [1, 2, 3, 4, 5]
b = ["a", "b", "c"]
print(list(zip(a, b))) # [(1, 'a'), (2, 'b'), (3, 'c')]
# zip_longest — usa el más largo (rellena con None o valor personalizado)
from itertools import zip_longest
print(list(zip_longest(a, b, fillvalue="?")))
# [(1, 'a'), (2, 'b'), (3, 'c'), (4, '?'), (5, '?')]
# Descomprimir con zip(*...)
pares = [(1, "uno"), (2, "dos"), (3, "tres")]
numeros, palabras = zip(*pares)
print(numeros) # (1, 2, 3)
print(palabras) # ('uno', 'dos', 'tres')Operaciones comunes con listas
# Concatenación
lista_a = [1, 2, 3]
lista_b = [4, 5, 6]
combinada = lista_a + lista_b
print(combinada) # [1, 2, 3, 4, 5, 6]
# Repetición
patron = [0, 1]
repetida = patron * 4
print(repetida) # [0, 1, 0, 1, 0, 1, 0, 1]
# Pertenencia
print(3 in lista_a) # True
print(10 not in lista_a) # True
# Funciones integradas útiles con listas
numeros = [3, 1, 4, 1, 5, 9, 2, 6, 5]
print(min(numeros)) # 1
print(max(numeros)) # 9
print(sum(numeros)) # 36
print(len(numeros)) # 9
# any() y all()
booleanos = [True, True, False, True]
print(any(booleanos)) # True — al menos uno es True
print(all(booleanos)) # False — no todos son True
numeros_positivos = [1, 3, 5, 7]
print(all(n > 0 for n in numeros_positivos)) # True
print(any(n > 6 for n in numeros_positivos)) # TrueListas anidadas (matrices)
# Crear una matriz 3x3
matriz = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
# Acceder a elementos
print(matriz[1][2]) # 6
# Iterar filas y columnas
for fila in matriz:
for elemento in fila:
print(elemento, end=" ")
print()
# Transponer una matriz
def transponer(mat: list[list[int]]) -> list[list[int]]:
return [[mat[j][i] for j in range(len(mat))] for i in range(len(mat[0]))]
transpuesta = transponer(matriz)
for fila in transpuesta:
print(fila)
# [1, 4, 7]
# [2, 5, 8]
# [3, 6, 9]Resumen
Las listas son la estructura de datos secuencial más poderosa de Python: mutables, indexables con valores negativos y con slicing avanzado. Las tuplas ofrecen inmutabilidad para datos que no deben cambiar. enumerate() y zip() son tus aliados para bucles elegantes. En la próxima lección dominaremos los diccionarios y conjuntos, las estructuras de datos clave para búsquedas eficientes.
Inicia sesión para guardar tu progreso