Cómo practicar con estos ejercicios de listas
Necesitas conocer las listas, los índices y el bucle for. Los últimos ejercicios usan también slicing.
- Lee el contrato: qué recibe la función y qué debe devolver.
- Escribe la función y añade debajo las comprobaciones.
- Ejecuta ambas partes. Un
assertque pasa no imprime nada; si falla, apareceAssertionError. - Antes de abrir la solución, prueba una lista vacía y una de un solo elemento: son los casos que más fallos esconden.
Cada solución usa return. Mostrar un valor con print no sustituye al resultado que espera recibir quien llama a la función.
Todas las soluciones incluyen sus pruebas y puedes abrirlas en el editor con el botón «Probar en el editor». Las comprobaciones son educativas y no sustituyen toda la validación de una aplicación real.
Leer y recorrer
Devuelve el último elemento
Escribe ultimo(lista). Devuelve el último elemento de una lista o None si está vacía.
assert ultimo([1, 2, 3]) == 3
assert ultimo(["a"]) == "a"
assert ultimo([]) is NoneVer una pista para el ejercicio 1
Una lista vacía no tiene índice -1. Comprueba si hay elementos antes de leer.
Ver solución y explicación del ejercicio 1
def ultimo(lista):
if not lista:
return None
return lista[-1]
assert ultimo([1, 2, 3]) == 3
assert ultimo(["a"]) == "a"
assert ultimo([]) is None
print("Pruebas superadas")Una lista vacía se considera falsa en una condición. Sin la comprobación, ultimo([]) produciría IndexError.
Calcula la media de una lista
Escribe media(numeros). Devuelve la media de una lista de números o None si la lista está vacía.
assert media([2, 4, 6]) == 4
assert media([5]) == 5
assert media([-1, 1]) == 0
assert media([]) is NoneVer una pista para el ejercicio 2
Suma con un acumulador o con sum y divide por la longitud, pero solo cuando haya elementos.
Ver solución y explicación del ejercicio 2
def media(numeros):
if not numeros:
return None
return sum(numeros) / len(numeros)
assert media([2, 4, 6]) == 4
assert media([5]) == 5
assert media([-1, 1]) == 0
assert media([]) is None
print("Pruebas superadas")Dividir entre len([]) produciría ZeroDivisionError, así que el caso vacío se decide antes de calcular.
Construir listas nuevas
Filtra los números negativos
Escribe sin_negativos(numeros). Devuelve una lista nueva con los números mayores o iguales que cero, conservando el orden. No modifica la lista recibida.
entrada = [3, -1, 0, -5, 8]
assert sin_negativos(entrada) == [3, 0, 8]
assert entrada == [3, -1, 0, -5, 8]
assert sin_negativos([]) == []
assert sin_negativos([-1, -2]) == []Ver una pista para el ejercicio 3
Crea una lista vacía y añade solo los valores que cumplan la condición.
Ver solución y explicación del ejercicio 3
def sin_negativos(numeros):
resultado = []
for numero in numeros:
if numero >= 0:
resultado.append(numero)
return resultado
entrada = [3, -1, 0, -5, 8]
assert sin_negativos(entrada) == [3, 0, 8]
assert entrada == [3, -1, 0, -5, 8]
assert sin_negativos([]) == []
assert sin_negativos([-1, -2]) == []
print("Pruebas superadas")La lista nueva protege la entrada original. El cero se conserva porque la condición dice mayor o igual.
Invierte una lista sin modificarla
Escribe invertir(lista). Devuelve una lista nueva con los elementos en orden inverso. La lista original no cambia.
original = [1, 2, 3]
assert invertir(original) == [3, 2, 1]
assert original == [1, 2, 3]
assert invertir([]) == []
assert invertir(["a"]) == ["a"]Ver una pista para el ejercicio 4
Un slice con paso -1 crea una copia al revés. El método reverse modifica la lista original y devuelve None.
Ver solución y explicación del ejercicio 4
def invertir(lista):
return lista[::-1]
original = [1, 2, 3]
assert invertir(original) == [3, 2, 1]
assert original == [1, 2, 3]
assert invertir([]) == []
assert invertir(["a"]) == ["a"]
print("Pruebas superadas")lista[::-1] recorre de final a inicio y produce un objeto nuevo. Si hubieras usado lista.reverse(), la prueba de la entrada original fallaría.
Combinar y transformar
Une dos listas sin repetidos
Escribe unir_sin_repetir(a, b). Devuelve una lista con los elementos de a y después los de b que aún no estén, sin repeticiones y en orden de aparición.
assert unir_sin_repetir([1, 2], [2, 3]) == [1, 2, 3]
assert unir_sin_repetir([], [1, 1]) == [1]
assert unir_sin_repetir([1, 1], []) == [1]
assert unir_sin_repetir(["a"], ["b", "a"]) == ["a", "b"]Ver una pista para el ejercicio 5
Construye el resultado paso a paso y pregunta con in antes de añadir. Un set no conserva el orden.
Ver solución y explicación del ejercicio 5
def unir_sin_repetir(a, b):
resultado = []
for elemento in a + b:
if elemento not in resultado:
resultado.append(elemento)
return resultado
assert unir_sin_repetir([1, 2], [2, 3]) == [1, 2, 3]
assert unir_sin_repetir([], [1, 1]) == [1]
assert unir_sin_repetir([1, 1], []) == [1]
assert unir_sin_repetir(["a"], ["b", "a"]) == ["a", "b"]
print("Pruebas superadas")a + b crea una lista temporal con todos los elementos. Preguntar por pertenencia en el resultado conserva la primera aparición y el orden.
Rota los elementos hacia la izquierda
Escribe rotar(lista, k). Devuelve una lista nueva con los elementos desplazados k posiciones hacia la izquierda; los primeros pasan al final. k puede ser mayor que la longitud y una lista vacía devuelve [].
assert rotar([1, 2, 3, 4], 1) == [2, 3, 4, 1]
assert rotar([1, 2, 3, 4], 5) == [2, 3, 4, 1]
assert rotar([1, 2, 3], 0) == [1, 2, 3]
assert rotar([], 3) == []Ver una pista para el ejercicio 6
Cuando k supera la longitud, solo importa el resto de dividir k entre len(lista). Combina dos slices.
Ver solución y explicación del ejercicio 6
def rotar(lista, k):
if not lista:
return []
k = k % len(lista)
return lista[k:] + lista[:k]
assert rotar([1, 2, 3, 4], 1) == [2, 3, 4, 1]
assert rotar([1, 2, 3, 4], 5) == [2, 3, 4, 1]
assert rotar([1, 2, 3], 0) == [1, 2, 3]
assert rotar([], 3) == []
print("Pruebas superadas")El resto k % len(lista) evita giros completos innecesarios. Con una lista vacía esa división produciría ZeroDivisionError, así que se resuelve antes.
Errores frecuentes en estos ejercicios
- IndexError al leer una posición
- Pides un índice que no existe, a menudo en una lista vacía. Consulta IndexError y comprueba la longitud antes de leer.
- La lista original cambia
- Métodos como
sort,reverseoappendmodifican la lista recibida. Si el contrato pide una lista nueva, construye una copia. - Se guarda None en lugar de una lista
- Esos métodos devuelven
None. No reasignes su retorno a la variable:lista = lista.append(x)destruye la lista. - La función falla con lista vacía
- Decide qué debe devolver antes de calcular:
None, una lista vacía o un error son contratos distintos.
Si no entiendes el traceback, empieza por su última línea en la guía de errores de Python.
Preguntas frecuentes sobre ejercicios de listas
¿Debo modificar la lista que recibo o crear una nueva?
Lo que diga el contrato. En estos ejercicios se crea una lista nueva para que quien llama conserve su entrada original.
¿Cuándo uso slicing y cuándo un bucle?
El slicing es ideal para tramos y copias. Un bucle es mejor cuando necesitas decidir elemento a elemento.
¿Puedo usar list comprehensions?
Sí, cuando puedas explicar la transformación en una frase. Si el bucle explícito te resulta más claro, úsalo: es una solución igual de válida.
Consulta datos por su nombre
Las listas se consultan por posición; los diccionarios, por nombre del dato.
Practicar diccionarios →Ver los 12 ejercicios de fundamentosFuentes y compatibilidad
Los ejemplos usan Python 3 y la biblioteca estándar. Las instrucciones de instalación se contrastaron con la documentación oficial; los ejemplos de código se verifican con las comprobaciones de estas guías.