Tiza Paso a paso
Practicar →

Pensamiento Computacional · Unidad 4 — Estructuras de datos

Listas

Una lista guarda varios valores en orden, bajo un solo nombre. A diferencia de un string, se puede modificar.

Practicar este tema →8 ejercicios que te corrigen paso a paso · gratis, sin cuenta

La explicación

Varios valores, un nombre

notas = [7, 4, 9, 6]

notas[0]   → 7       notas[-1]  → 6
len(notas)  → 4       notas[1:3]  → [4, 9]

Se indexa igual que un string: desde 0, con negativos desde el final, y con rebanadas que no incluyen el límite derecho. Todo lo que aprendiste de strings sirve acá.

Una lista puede mezclar tipos — [1, "hola", True] es válida — aunque en la práctica casi siempre guardan cosas del mismo tipo.

La diferencia con un string: se puede modificar

notas[0] = 10     # esto funciona
"hola"[0] = "H"   # esto da error

Las listas son mutables. Eso abre posibilidades y también trae el problema del tema 4.2.

Agregar y sacar

notas.append(8)     agrega al final
notas.insert(0, 5)   inserta en una posición
notas.remove(4)     saca la primera aparición del valor 4
notas.pop()         saca el último y lo devuelve
notas.pop(0)        saca el de la posición 0
remove borra por valor, pop por posición. Con [10, 20, 30], remove(0) tira error porque no hay ningún 0 en la lista, mientras que pop(0) saca el 10. Confundirlos es muy común.

Preguntar y contar

3 in [1, 2, 3]     → True
sum([1, 2, 3])     → 6
max([4, 9, 2])     → 9
min([4, 9, 2])     → 2
len([4, 9, 2])     → 3

Con sum y len el promedio sale en una línea: sum(notas) / len(notas).

Armar una lista desde cero

El patrón más usado: empezar vacía y llenarla en un ciclo.

cuadrados = []                # afuera
for n in range(1, 5):
    cuadrados.append(n * n)
print(cuadrados)           # [1, 4, 9, 16]

Es el mismo esquema del acumulador, pero juntando valores en vez de sumarlos. Y con la misma trampa: la lista vacía va afuera del ciclo.

Un ejercicio resuelto, paso a paso

Escribir una función que reciba una lista de notas y devuelva cuántas están aprobadas (7 o más).

El patrón es contar: un contador afuera, y adentro del ciclo se suma 1 cuando se cumple la condición.

def cuantas_aprobadas(notas):
    cuenta = 0
    for n in notas:
        if n >= 7:
            cuenta = cuenta + 1
    return cuenta

Con [7, 4, 9, 6]: el 7 cuenta, el 4 no, el 9 sí, el 6 no. Devuelve 2.

Fijate que recorrimos for n in notas y no for i in range(len(notas)). Como sólo necesitamos los valores y no las posiciones, la primera forma es más corta y más clara. Reservá la del range para cuando de verdad necesites el índice.

Control: probá con la lista vacía []. Tiene que devolver 0, no tirar error. El ciclo simplemente no da ninguna vuelta y devuelve el contador como estaba. Las funciones que reciben listas siempre hay que probarlas con la lista vacía.

Y uno del nivel del parcial

Escribir una función que reciba una lista de notas y devuelva una tupla con la cantidad de aprobados (7 o más), el promedio general y el promedio de los aprobados. Tiene que funcionar también con la lista vacía y cuando no hay ningún aprobado.

Los casos borde son la mitad del ejercicio, y conviene listarlos antes de escribir código:

lista vacía        → no hay promedio: dividir por 0 rompe
ningún aprobado   → hay promedio general pero no de aprobados
todos aprobados   → los dos promedios coinciden

La función:

def resumen(notas):
    if len(notas) == 0:
        return (0, None, None)
    aprobados = [n for n in notas if n >= 7]
    promedio = sum(notas) / len(notas)
    prom_aprob = sum(aprobados) / len(aprobados) if aprobados else None
    return (len(aprobados), promedio, prom_aprob)

La primera línea protege de la división por cero, y devuelve None donde no hay número que devolver. Devolver 0 sería mentir: un promedio de 0 significaría que todos sacaron 0, que es otra cosa que no tener alumnos.

La comprensión de lista [n for n in notas if n >= 7] arma la lista de los aprobados en una línea. La versión con ciclo, por si el parcial la pide explícita:

aprobados = []
for n in notas:
    if n >= 7:
        aprobados.append(n)

El if aprobados else None del final es la segunda protección: si la lista de aprobados quedó vacía, len(aprobados) es 0 y la división rompería. En Python una lista vacía se evalúa como falsa, así que if aprobados alcanza.

Las pruebas, una por caso borde:

resumen([4, 7, 9, 2, 8]) → (3, 6.0, 8.0)
resumen([])              → (0, None, None)
resumen([2, 3])         → (0, 2.5, None)
resumen([7, 10])       → (2, 8.5, 8.5)

El control a mano del primer caso:

suma = 4+7+9+2+8 = 30,  30/5 = 6.0 ✓
aprobados: 7, 9, 8  → 24/3 = 8.0 ✓

Y un control que vale para cualquier entrada: el promedio de los aprobados tiene que ser mayor o igual que el general, porque los aprobados son los de arriba. Acá 8.0 ≥ 6.0 ✓. Si te diera al revés, hay un error de filtro.

Por qué devolver una tupla y no imprimir tres líneas. Quien llama a la función decide qué hacer con los tres números: mostrarlos, guardarlos, o usarlos en otra cuenta. Una función que imprime obliga a mostrarlos siempre.

Cómo se usa el resultado:

cantidad, general, de_aprobados = resumen([4, 7, 9, 2, 8])
print(cantidad, general, de_aprobados) # 3 6.0 8.0

Dónde se pierde el punto: no contemplar la lista vacía. El programa "anda" con todos los datos de prueba del enunciado y se rompe con el caso que el corrector va a probar primero, que es justo el vacío.

Dónde se cae la mayoría

Hasta acá la explicación. La práctica es la otra mitad: 8 ejercicios de este tema, en cuatro niveles, que no te dicen sólo si está bien al final sino que te corrigen en cada paso y te explican por qué. Y uno para escribir el programa vos, que se prueba ejecutándolo en Python ahí mismo, en el navegador. Además trae una animación que muestra la idea en movimiento.

Practicar Listas →

Dónde entra este tema en el parcial

Los otros temas de la unidad 4

Estructuras de datos

Ver todos los temas de Pensamiento Computacional