Listas
Una variable guarda una sola cosa. Una lista guarda muchas cosas en orden, todas bajo un mismo nombre. Una tabla de posiciones es una secuencia ordenada de puntajes. Un quiz es una colección de preguntas. Cuando necesitas manejar un grupo de valores relacionados, necesitas una lista.
Crear una lista
Corchetes, valores separados por comas. Las listas pueden contener cualquier combinación de tipos, y una lista vacía es válida y común como punto de partida que vas construyendo con el tiempo.
scores = [87, 92, 74, 65, 91]
players = ["Ana", "Beto", "Carla"]
mixed = ["Ana", 87, True, 3.14] # cualquier tipo, aunque no es lo común
empty = [][] vacío es un buen punto de partida cuando planeas llenarlo poco a poco. La mayoría de mis listas empiezan así, vacías y esperando. Indexado y slicing
Las listas usan la misma numeración que las cadenas: las posiciones empiezan en 0, y los números negativos cuentan desde el final. Puedes leer cualquier elemento por su posición. Como las listas son mutables, también puedes escribir en una posición específica.
scores = [87, 92, 74, 65, 91]
scores[0] # 87 (primero)
scores[-1] # 91 (último)
scores[1:3] # [92, 74]
scores[:2] # [87, 92]
scores[::-1] # [91, 65, 74, 92, 87] (invertido)
scores[0] = 90 # mutable: funciona (las cadenas lanzarían TypeError)0, y los números negativos cuentan hacia atrás desde el final, así que scores[-1] es el último. Un slice como scores[1:3] te entrega una lista nueva con las posiciones 1 y 2. Lo que me costó un momento entender: con una lista también puedes escribir en una posición, scores[0] = 90, donde una cadena se negaría. Agregar elementos
Tres métodos para agregar elementos. append() agrega un solo elemento al final y es el que usarás casi siempre. insert() agrega en una posición específica. extend() fusiona otra lista.
scores = [87, 92, 74]
scores.append(65) # [87, 92, 74, 65]
scores.insert(1, 100) # [87, 100, 92, 74, 65]
scores.extend([55, 71]) # [87, 100, 92, 74, 65, 55, 71]Un error común: append() con una lista agrega toda la lista como un solo elemento, dándote una lista dentro de otra lista. Usa extend() para fusionar en su lugar:
scores.append([55, 71]) # [..., [55, 71]] lista anidada, probablemente un error
scores.extend([55, 71]) # [..., 55, 71] fusionado, correctoappend() pega un elemento al final y es el que usarás casi siempre. insert() coloca un elemento en una posición, extend() fusiona otra lista. El error clásico: usar append() con una lista te da una lista dentro de tu lista, así que usa extend() cuando quieras fusionar. Eliminar elementos
Cuatro herramientas para eliminar elementos. remove() busca por valor. pop() elimina por posición y te devuelve el elemento. del elimina por posición sin devolver nada. clear() vacía toda la lista.
scores = [87, 92, 74, 65, 91]
scores.remove(74) # elimina la primera aparición de 74
scores.pop() # elimina y devuelve el último elemento (91)
scores.pop(0) # elimina y devuelve el elemento en la posición 0 (87)
del scores[1] # elimina en la posición 1, sin valor de retorno
scores.clear() # elimina todoremove() lanza un ValueError si el valor no está en la lista. Verifica con in primero si no estás seguro:
if 74 in scores:
scores.remove(74)remove() elimina por valor y solo la primera coincidencia, y lanza ValueError si el valor no está ahí, así que verifica con in primero si no estás seguro. pop() elimina por posición y te devuelve el elemento, del elimina por posición y no te devuelve nada. Ordenamiento
sorted() devuelve una lista nueva ordenada y deja tu original intacta. .sort() ordena la lista en el mismo lugar y devuelve None. Esa diferencia importa más de lo que parece.
scores = [87, 42, 96, 55, 71]
ranked = sorted(scores) # [42, 55, 71, 87, 96] (lista nueva)
scores.sort() # ordena en el mismo lugar, devuelve None
scores.sort(reverse=True) # [96, 87, 71, 55, 42]
result = scores.sort() # result es None, no la lista ordenadasorted() te da una lista nueva ordenada y deja el original intacto. .sort() reorganiza la lista misma y devuelve None, así que x = scores.sort() te deja con None, no con la lista. Cometí ese mismo error más de una vez antes de que se me quedara claro. Operaciones útiles
Python tiene un conjunto de herramientas integradas que funcionan directamente sobre listas. len(), sum(), min(), y max() son las cuatro que usarás constantemente.
scores = [87, 92, 74, 65, 91]
len(scores) # 5
sum(scores) # 409
min(scores) # 65
max(scores) # 92
scores.count(87) # 1
scores.index(74) # 2
74 in scores # True
74 not in scores # False
scores.copy() # copia superficial
scores.reverse() # invierte en el mismo lugarlen(), sum(), min(), y max() funcionan directamente sobre una lista, sin preparación previa. in pregunta si algo está presente, .count() cuenta cuántas veces aparece, y .index() encuentra la posición de la primera coincidencia. Iteración
Un bucle for recorre una lista un elemento a la vez. La variable después de for recibe cada elemento en su turno. Cuando también necesitas la posición, enumerate() te da ambas cosas sin un contador manual.
players = ["Ana", "Beto", "Carla"]
for player in players:
print(player)
for i, player in enumerate(players, start=1):
print(f"{i}. {player}")
# 1. Ana
# 2. Beto
# 3. Carlafor y enumerate() se tratan en profundidad en el capítulo de Control de flujo. La versión corta: for player in players se ejecuta una vez por cada elemento, y enumerate() te da tanto la posición como el valor en cada iteración.
for recorre la lista un elemento a la vez, y el nombre después de for se convierte en ese elemento en cada turno. Cuando también quieres la posición, enumerate() te da ambas cosas, así que nunca tienes que mantener un contador tú mismo. Dejar que él cuente por mí me evitó un montón de errores de desfase. Listas anidadas
Una lista puede contener otras listas. Así es como representas una cuadrícula o una tabla: una lista de filas, donde cada fila es una lista de valores. Dos pares de corchetes acceden a un elemento: el primero elige la fila, el segundo elige la columna.
grid = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]
grid[0] # [1, 2, 3]
grid[1][2] # 6 (fila 1, columna 2)grid[1][2], el primero elige la fila, el segundo elige dentro de ella. Mutabilidad: la trampa
Esto sorprende a casi todo el mundo. Asignar una lista a una variable nueva no crea una copia. Ambos nombres apuntan a la misma lista. Cambias una y cambias la otra. Para obtener una copia independiente, tienes que pedirla explícitamente.
a = [1, 2, 3]
b = a # b no es una copia; apunta a la misma lista
b.append(4)
print(a) # [1, 2, 3, 4] (cambió: a y b son la misma lista)b = a.copy() # copia independiente
b = list(a) # mismo resultado
b = a[:] # también lo mismo
# Las listas anidadas siguen compartiendo sus objetos internos:
matrix = [[1, 2], [3, 4]]
copy = matrix.copy()
copy[0].append(99)
print(matrix) # [[1, 2, 99], [3, 4]] (la lista interna se compartía)b = a no crea una copia, ambos nombres apuntan a la misma lista, así que un cambio a través de uno se refleja en el otro. Para una lista independiente tienes que pedirla: .copy(), list(a), o a[:]. Esta sorprende a casi todo el mundo la primera vez, a mí incluido. Más métodos
| Método | Qué hace |
|---|---|
.append(item) | Agregar al final |
.insert(i, item) | Insertar en la posición i |
.extend(iterable) | Agregar todos los elementos de un iterable |
.remove(value) | Eliminar la primera aparición del valor |
.pop(i) | Eliminar y devolver el elemento en la posición i (por defecto: el último) |
.clear() | Eliminar todos los elementos |
.index(value) | Posición de la primera aparición |
.count(value) | Número de apariciones |
.sort() | Ordenar en el mismo lugar |
.reverse() | Invertir en el mismo lugar |
.copy() | Devolver una copia superficial |
En la práctica
Construyendo un rastreador de puntajes: agregar resultados, ordenarlos e imprimir un resumen.
scores = []
scores.append(87)
scores.append(54)
scores.append(92)
scores.append(67)
scores.append(45)
scores.sort(reverse=True)
print(f"Puntajes ordenados: {scores}")
print(f"Más alto: {scores[0]}")
print(f"Más bajo: {scores[-1]}")
print(f"Promedio: {sum(scores) / len(scores):.1f}")
print(f"Top 3: {scores[:3]}")
