Listas en Python: guía y ejercicios resueltos
Actualizado el 29 de septiembre de 2026
Una lista es una colección ordenada de valores. Es la estructura de datos que más vas a usar en Python: sirve para guardar las notas de un curso, los productos de un carrito o las líneas de un archivo. Los elementos mantienen el orden en que los agregas, se pueden repetir y la lista puede crecer o achicarse mientras el programa corre.
En esta guía vas a ver cómo crear una lista, leer y cambiar sus elementos, recorrerla, cortarla en pedazos y ordenarla. Al final hay tres ejercicios resueltos de dificultad creciente.
Crear una lista y leer sus elementos
Una lista se escribe entre corchetes, con los elementos separados por comas. Cada elemento tiene una posición, llamada índice, que empieza en 0. Los índices negativos cuentan desde el final: -1 es el último elemento.
frutas = ["manzana", "pera", "uva"]
print(frutas[0]) # manzana
print(frutas[-1]) # uva
print(len(frutas)) # 3len() devuelve cuántos elementos tiene la lista. Como los índices empiezan en 0, el último índice válido siempre es len(lista) - 1.
Agregar, quitar y cambiar elementos
Las listas son mutables: se pueden modificar sin crear una lista nueva. Estos son los métodos que más se usan:
frutas = ["manzana", "pera", "uva"]
frutas.append("kiwi") # agrega al final
# ['manzana', 'pera', 'uva', 'kiwi']
frutas.insert(1, "plátano") # agrega en la posición 1
# ['manzana', 'plátano', 'pera', 'uva', 'kiwi']
frutas.remove("pera") # quita la primera aparición de "pera"
# ['manzana', 'plátano', 'uva', 'kiwi']
ultima = frutas.pop() # quita el último y lo devuelve
# ultima == 'kiwi'
frutas[0] = "naranja" # reemplaza el elemento en la posición 0
# ['naranja', 'plátano', 'uva']remove() lanza un ValueError si el elemento no está en la lista, y pop() lanza un IndexError si la lista está vacía. Si no estás seguro, comprueba antes con in o con len().
Recorrer una lista
La forma más directa de recorrer una lista es con for. Si además necesitas la posición de cada elemento, usa enumerate(), que entrega pares de índice y valor:
frutas = ["naranja", "plátano", "uva"]
for i, fruta in enumerate(frutas):
print(i, fruta)
# 0 naranja
# 1 plátano
# 2 uvaEs común ver for i in range(len(frutas)) en código de principiantes. Funciona, pero enumerate() es más claro y evita errores de índice.
Slicing: obtener una parte de la lista
Con la notación lista[inicio:fin] obtienes una lista nueva con los elementos desde inicio hasta fin, sin incluir fin. Si omites uno de los extremos, se toma desde el principio o hasta el final. Un tercer valor opcional indica el paso.
numeros = [10, 20, 30, 40, 50]
numeros[1:3] # [20, 30]
numeros[:2] # [10, 20]
numeros[3:] # [40, 50]
numeros[-2:] # [40, 50] (los dos últimos)
numeros[::2] # [10, 30, 50] (uno por medio)
numeros[::-1] # [50, 40, 30, 20, 10] (invertida)El slicing nunca modifica la lista original y no lanza error si los índices se salen del rango: simplemente devuelve lo que haya.
Buscar, sumar y ordenar
notas = [5.5, 3.9, 6.8, 4.0]
6.8 in notas # True
notas.index(3.9) # 1 (posición de la primera aparición)
min(notas) # 3.9
max(notas) # 6.8
sum(notas) # 20.2
sorted(notas) # [3.9, 4.0, 5.5, 6.8] (lista nueva)
notas # [5.5, 3.9, 6.8, 4.0] (no cambió)
notas.sort(reverse=True) # ordena la misma lista, de mayor a menor
notas # [6.8, 5.5, 4.0, 3.9]La diferencia entre sorted() y .sort() es importante: sorted() devuelve una lista nueva y deja la original intacta, mientras que .sort() ordena la lista en su lugar y devuelve None.
Errores comunes
Guardar el resultado de .sort()
lista = [3, 1, 2]
lista = lista.sort()
print(lista) # None.sort() modifica la lista y devuelve None, así que al asignar el resultado pierdes la lista. Usa lista.sort() sin asignar, o lista = sorted(lista). Lo mismo pasa con append(), insert() y reverse().
Modificar la lista mientras la recorres
numeros = [1, 2, 4, 5]
for n in numeros:
if n % 2 == 0:
numeros.remove(n)
print(numeros) # [1, 4, 5] ¡el 4 sigue ahí!Al quitar el 2, todos los elementos se corren una posición hacia la izquierda y el for se salta el 4. La solución es construir una lista nueva con los elementos que quieres conservar:
numeros = [1, 2, 4, 5]
numeros = [n for n in numeros if n % 2 != 0]
print(numeros) # [1, 5]Creer que b = a copia la lista
a = [1, 2, 3]
b = a
b.append(4)
print(a) # [1, 2, 3, 4]La asignación no copia la lista: a y b son dos nombres para la misma lista. Para tener una copia independiente usa a.copy(), list(a) o a[:].
IndexError: list index out of range
Aparece al pedir una posición que no existe, casi siempre por usar lista[len(lista)] o por recorrer con un rango que se pasa en uno. Recuerda que en una lista de 3 elementos los índices válidos son 0, 1 y 2 (o -1, -2 y -3).
Ejercicios resueltos
Intenta resolver cada ejercicio antes de abrir la solución: equivocarse y corregir es la parte que más enseña.
1.Sumar los números pares
Escribe una función suma_pares(numeros) que reciba una lista de enteros y devuelva la suma de los que son pares. Si no hay ninguno, debe devolver 0.
suma_pares([1, 2, 3, 4, 10])→16suma_pares([1, 3])→0suma_pares([])→0
def suma_pares(numeros):
...Ver soluciónOcultar solución
def suma_pares(numeros):
total = 0
for n in numeros:
if n % 2 == 0:
total += n
return totalSe parte con un acumulador en 0 y se recorre la lista sumando solo los números cuyo resto al dividir por 2 es 0. Como el acumulador parte en 0, una lista vacía o sin pares devuelve 0 sin casos especiales. Los negativos también funcionan: -2 % 2 es 0 en Python.
Cuando te sientas cómodo con los bucles, la misma idea cabe en una línea: return sum(n for n in numeros if n % 2 == 0).
2.Quitar duplicados sin perder el orden
Escribe una función sin_duplicados(lista) que devuelva una lista nueva con los elementos de la original, sin repetidos y en el orden en que aparecieron por primera vez.
sin_duplicados([3, 1, 3, 2, 1])→[3, 1, 2]sin_duplicados(["a", "b", "a"])→["a", "b"]
def sin_duplicados(lista):
...Ver soluciónOcultar solución
def sin_duplicados(lista):
resultado = []
vistos = set()
for elemento in lista:
if elemento not in vistos:
vistos.add(elemento)
resultado.append(elemento)
return resultadoLa tentación es escribir list(set(lista)), pero un conjunto no guarda el orden, así que el resultado puede salir desordenado. En cambio, se recorre la lista una vez y se agrega cada elemento solo la primera vez que aparece.
El conjunto vistos sirve para preguntar rápido si un elemento ya apareció. Preguntar elemento not in resultado también funciona, pero en una lista esa búsqueda recorre todos los elementos cada vez, y con listas grandes se nota.
3.Rotar una lista
Escribe una función rotar(lista, k) que devuelva la lista rotada k posiciones hacia la derecha: los últimos k elementos pasan al principio. k puede ser mayor que el largo de la lista, y la lista puede venir vacía.
rotar([1, 2, 3, 4, 5], 2)→[4, 5, 1, 2, 3]rotar([1, 2, 3], 4)→[3, 1, 2]rotar([], 3)→[]
def rotar(lista, k):
...Ver soluciónOcultar solución
def rotar(lista, k):
if not lista:
return []
k = k % len(lista)
return lista[-k:] + lista[:-k]Rotar una lista de 3 elementos 3 veces la deja igual, así que rotar 4 veces es lo mismo que rotar 1. Por eso se reduce k con el resto de la división: k % len(lista). Esa división fallaría con una lista vacía, y por eso ese caso se resuelve primero.
Después, lista[-k:] son los últimos k elementos y lista[:-k] todos los demás; basta con unirlos. Cuando k queda en 0, lista[-0:] es la lista completa y lista[:-0] es una lista vacía, así que el resultado es la lista sin cambios, que es justo lo correcto.