Saltar al contenido
listas.py · devschool

Listas en Python

Lección 7 de 19 · 9 min de lectura · Actualizado el

En esta lección
  1. Crear una lista
  2. Acceder a los elementos: índices
  3. Slicing: trozos de una lista
  4. Añadir elementos
  5. Quitar elementos
  6. Buscar: in, index y count
  7. Funciones útiles: len, sum, min, max
  8. Ordenar: sort frente a sorted
  9. Copiar listas: referencias frente a copias
  10. Listas anidadas
  11. Desempaquetado
  12. Recorrer una lista con enumerate
  13. Listas y textos
  14. Errores frecuentes
  15. Resumen

Una lista guarda varios valores en orden dentro de una sola variable. Es la colección más usada de Python y el equivalente a los arrays de otros lenguajes. En esta lección aprenderás a crear listas, leer y cambiar sus elementos, sacar trozos, añadir y quitar, ordenar, y un detalle que causa muchos errores: la diferencia entre copiar una lista y tener dos nombres para la misma.

Crear una lista

Los elementos van entre corchetes y separados por comas:

frutas = ["manzana", "pera", "kiwi"]
notas = [7, 9.5, 5, 8]
mezcla = ["Ana", 25, True]      # puede mezclar tipos
vacia = []
letras = list("hola")           # ['h', 'o', 'l', 'a']
numeros = list(range(1, 6))     # [1, 2, 3, 4, 5]

Aunque se pueden mezclar tipos, lo normal es que todos los elementos sean del mismo tipo: una lista de nombres, una lista de precios…

Las listas son ordenadas (mantienen el orden en que metes los elementos), admiten duplicados y son mutables: puedes cambiarlas después de crearlas, al contrario que las cadenas.

Acceder a los elementos: índices

Cada elemento tiene una posición que empieza en 0. Los índices negativos cuentan desde el final:

frutas = ["manzana", "pera", "kiwi", "uva"]
print(frutas[0])    # manzana
print(frutas[2])    # kiwi
print(frutas[-1])   # uva (el último)
print(frutas[-2])   # kiwi (el penúltimo)
print(len(frutas))  # 4

frutas[-1] es la forma habitual de obtener el último elemento sin saber cuántos hay.

Para cambiar un elemento, asígnale un valor nuevo:

frutas[1] = "mango"
print(frutas)
# ['manzana', 'mango', 'kiwi', 'uva']

Si pides una posición que no existe, obtienes IndexError: list index out of range. En una lista de 4 elementos, el último índice válido es 3.

Slicing: trozos de una lista

lista[inicio:fin:paso] devuelve una lista nueva con los elementos desde inicio hasta fin sin incluirlo:

numeros = [10, 20, 30, 40, 50, 60]

print(numeros[1:4])    # [20, 30, 40]
print(numeros[:3])     # [10, 20, 30]  los tres primeros
print(numeros[3:])     # [40, 50, 60]  desde el índice 3 al final
print(numeros[-2:])    # [50, 60]      los dos últimos
print(numeros[::2])    # [10, 30, 50]  uno sí, uno no
print(numeros[::-1])   # [60, 50, 40, 30, 20, 10] al revés
print(numeros[:])      # copia completa

Una forma de recordarlo: lista[:n] son los n primeros y lista[-n:] los n últimos. Y lista[:n] + lista[n:] siempre reconstruye la lista original.

El slicing no da error si los límites se salen: numeros[4:100] devuelve [50, 60].

También puedes asignar a un trozo para reemplazar varios elementos de golpe:

numeros = [10, 20, 30, 40, 50]
numeros[1:3] = [0, 0, 0]
print(numeros)
# [10, 0, 0, 0, 40, 50]

Añadir elementos

tareas = ["estudiar"]

tareas.append("comprar")               # añade un elemento al final
tareas.insert(0, "desayunar")          # inserta en una posición
tareas.extend(["entrenar", "leer"])    # añade todos los de otra lista
print(tareas)
# ['desayunar', 'estudiar', 'comprar', 'entrenar', 'leer']

Fíjate en la diferencia entre append y extend con una lista:

a = [1, 2]
a.append([3, 4])
print(a)   # [1, 2, [3, 4]]  mete la lista entera como un elemento

b = [1, 2]
b.extend([3, 4])
print(b)   # [1, 2, 3, 4]    mete cada elemento

También puedes unir listas con + (crea una nueva) y repetirlas con *: [0] * 5 da [0, 0, 0, 0, 0].

Quitar elementos

tareas = ["desayunar", "estudiar", "comprar", "entrenar"]

tareas.remove("comprar")   # borra por valor (el primero que encuentre)
ultima = tareas.pop()      # quita el último y lo devuelve
primera = tareas.pop(0)    # quita el de la posición 0 y lo devuelve
print(ultima, primera)     # entrenar desayunar
print(tareas)              # ['estudiar']

del tareas[0]              # borra por posición, sin devolver nada
tareas.clear()             # vacía la lista
print(tareas)              # []
MétodoBorra porDevuelve el elementoSi no existe
remove(valor)ValorNoValueError
pop(indice)Posición (por defecto, la última)SíIndexError
del lista[i]Posición o trozoNoIndexError
clear()TodoNo—

pop es muy útil para procesar elementos uno a uno, por ejemplo una cola de pedidos.

Buscar: in, index y count

colores = ["rojo", "verde", "azul", "verde"]

print("azul" in colores)        # True
print("negro" not in colores)   # True
print(colores.index("verde"))   # 1: posición de la primera aparición
print(colores.count("verde"))   # 2

index lanza ValueError si el valor no está. Por eso conviene comprobar antes con in:

if "negro" in colores:
    print(colores.index("negro"))
else:
    print("No está")
# No está

Funciones útiles: len, sum, min, max

notas = [7, 9, 5, 8]

print(len(notas))                # 4
print(sum(notas))                # 29
print(max(notas))                # 9
print(min(notas))                # 5
print(sum(notas) / len(notas))   # 7.25 (la media)

min y max también funcionan con textos (orden alfabético). sum solo con números.

Ordenar: sort frente a sorted

Hay dos formas de ordenar y la diferencia es importante:

  • lista.sort() modifica la propia lista y devuelve None.
  • sorted(lista) devuelve una lista nueva ordenada y deja la original igual.
notas = [7, 3, 9, 5]

ordenadas = sorted(notas)
print(ordenadas)   # [3, 5, 7, 9]
print(notas)       # [7, 3, 9, 5]  sin cambios

notas.sort(reverse=True)   # de mayor a menor
print(notas)       # [9, 7, 5, 3]

Usa sorted cuando necesites conservar el orden original, y sort cuando no.

Ordenar con un criterio: key

El parámetro key recibe una función que se aplica a cada elemento para decidir el orden:

nombres = ["eva", "Luis", "ana", "Marta"]
print(sorted(nombres))                  # ['Luis', 'Marta', 'ana', 'eva']
print(sorted(nombres, key=str.lower))   # ['ana', 'eva', 'Luis', 'Marta']
print(sorted(nombres, key=len))         # ['eva', 'ana', 'Luis', 'Marta']

Sin key, las mayúsculas van antes que las minúsculas. Con key=str.lower se ordena sin distinguirlas. Para criterios más complejos se usan funciones lambda, que verás en Funciones avanzadas.

Cuidado: notas = notas.sort() deja notas valiendo None, porque sort no devuelve nada. Es uno de los errores más típicos.

Otros dos métodos: lista.reverse() invierte la lista en su sitio, y reversed(lista) permite recorrerla al revés sin modificarla.

Copiar listas: referencias frente a copias

Esto sorprende a casi todo el mundo la primera vez:

original = ["pan", "leche"]
otra = original          # NO es una copia
otra.append("huevos")
print(original)
# ['pan', 'leche', 'huevos']

Una variable no “contiene” la lista, sino que apunta a ella. Con otra = original tienes dos nombres para la misma lista, así que un cambio por un nombre se ve por el otro.

Para obtener una copia independiente:

original = ["pan", "leche"]
copia = original.copy()     # también: original[:] o list(original)
copia.append("huevos")
print(original)   # ['pan', 'leche']
print(copia)      # ['pan', 'leche', 'huevos']

Pasa lo mismo al enviar una lista a una función: si la función la modifica, modifica la original.

Cuidado: copy() hace una copia superficial. Si la lista contiene otras listas, esas listas interiores siguen compartidas. Para copiarlo todo, usa copy.deepcopy(lista) del módulo copy.

Listas anidadas

Una lista puede contener otras listas. Así se representan tablas o cuadrículas:

notas_clase = [
    ["Ana", 8, 9],
    ["Luis", 5, 6],
    ["Eva", 7, 10],
]

print(notas_clase[1])       # ['Luis', 5, 6]
print(notas_clase[1][0])    # Luis
print(notas_clase[2][2])    # 10

for alumno in notas_clase:
    media = (alumno[1] + alumno[2]) / 2
    print(f"{alumno[0]}: {media}")
# Ana: 8.5
# Luis: 5.5
# Eva: 8.5

El primer índice elige la fila y el segundo, la columna.

Desempaquetado

Puedes repartir los elementos de una lista entre varias variables:

coordenadas = [40.4, -3.7]
latitud, longitud = coordenadas
print(latitud, longitud)
# 40.4 -3.7

El número de variables debe coincidir con el de elementos; si no, ValueError. Con un asterisco recoges “el resto”:

clasificacion = ["Eva", "Ana", "Luis", "Marta", "Pablo"]
primero, segundo, *resto = clasificacion
print(primero)   # Eva
print(resto)     # ['Luis', 'Marta', 'Pablo']

Esto se combina muy bien con los bucles: for nombre, nota1, nota2 in notas_clase: desempaqueta cada fila.

Recorrer una lista con enumerate

Para recorrer una lista con su posición, usa enumerate (lo tienes en detalle en Bucles):

podio = ["Eva", "Ana", "Luis"]
for puesto, nombre in enumerate(podio, start=1):
    print(f"{puesto}.º {nombre}")
# 1.º Eva
# 2.º Ana
# 3.º Luis

Listas y textos

split convierte un texto en lista y join hace lo contrario:

frase = "aprender a programar"
palabras = frase.split()      # ['aprender', 'a', 'programar']
print("-".join(palabras))     # aprender-a-programar

Y para crear una lista a partir de otra en una línea (por ejemplo, los precios con IVA) existen las comprensiones: [p * 1.21 for p in precios]. Tienen su propia lección: Comprensiones de listas.

Errores frecuentes

  • IndexError: el último índice es len(lista) - 1, no len(lista).
  • lista = lista.sort(): deja la variable en None. Usa lista.sort() solo, o sorted(lista).
  • Creer que b = a copia: usa a.copy().
  • append con una lista cuando querías extend.
  • remove de un valor que no está: ValueError. Comprueba con in.
  • Borrar mientras recorres: for x in lista: lista.remove(x) se salta elementos. Recorre una copia o crea una lista nueva.

Resumen

TareaCómo
Crear[1, 2, 3], [], list(...)
Leer / cambiarlista[0], lista[-1], lista[i] = x
Trozolista[1:4], lista[:3], lista[::-1]
Añadirappend, insert, extend, +
Quitarremove, pop, del, clear
Buscarin, index, count
Calcularlen, sum, min, max
Ordenarsort() (en su sitio), sorted() (nueva), key, reverse
Copiarcopy(), [:], copy.deepcopy()
Desempaquetara, b = lista, a, *resto = lista

Si necesitas una secuencia que no cambie o una colección sin duplicados, sigue con Tuplas y conjuntos.

Pon a prueba lo que has aprendido

[Python] ¿Qué muestra este código?
frutas = ["pera", "uva", "kiwi"]
print(frutas[-1])

[Python] ¿Qué muestra este código?
numeros = [3, 1, 2]
numeros.append(5)
print(len(numeros))

[Python] ¿Qué muestra este código?
a = [1, 2]
b = a
b.append(3)
print(a)

[Python] ¿Qué muestra este código?
notas = [3, 1, 2]
notas = notas.sort()
print(notas)

¿Te ha quedado claro? Márcala y verás tu progreso en el explorador.