Python tiene formas más expresivas de iterar que el clásico for i in range(len(lista)). Las funciones enumerate(), zip() y el método items() eliminan el índice manual, hacen el código más legible y evitan una categoría entera de bugs de índice fuera de rango.
enumerate() en lugar de range(len())
enumerate(iterable, start=0) devuelve pares (índice, elemento) sin necesidad de acceder por índice:
frutas = ["manzana", "pera", "naranja"]
# Forma antigua y propensa a bugs
for i in range(len(frutas)):
print(i, frutas[i])
# Forma idiomática con enumerate
for i, fruta in enumerate(frutas):
print(i, fruta)
# start=1 para numeración desde 1
for n, fruta in enumerate(frutas, start=1):
print(f"{n}. {fruta}")
# 1. manzana
# 2. pera
# 3. naranja
zip() para recorrer dos listas en paralelo
zip() empareja elementos de múltiples iterables. Se detiene cuando el más corto se agota:
nombres = ["Ana", "Luis", "María"]
edades = [28, 34, 22]
ciudades = ["Madrid", "Barcelona", "Sevilla"]
for nombre, edad, ciudad in zip(nombres, edades, ciudades):
print(f"{nombre}, {edad} años, {ciudad}")
# Ana, 28 años, Madrid
# Luis, 34 años, Barcelona
# María, 22 años, Sevilla
# Crear un diccionario con zip
persona = dict(zip(nombres, edades))
print(persona) # {'Ana': 28, 'Luis': 34, 'María': 22}
zip_longest() cuando las listas tienen distinto tamaño
from itertools import zip_longest
precios = [10.5, 8.0, 15.0]
nombres = ["manzana", "pera", "uva", "naranja"]
for nombre, precio in zip_longest(nombres, precios, fillvalue=0.0):
print(f"{nombre}: {precio}")
# manzana: 10.5
# pera: 8.0
# uva: 15.0
# naranja: 0.0
dict.items() para clave y valor a la vez
inventario = {"manzanas": 150, "peras": 80, "naranjas": 210}
# Evita hacer inventario[producto] dentro del bucle
for producto, cantidad in inventario.items():
if cantidad < 100:
print(f"AVISO: pocas {producto} ({cantidad} unidades)")
# Solo claves
for producto in inventario: # equivalente a inventario.keys()
print(producto)
# Solo valores
for cantidad in inventario.values():
print(cantidad)
Cómo no usar sorted() y reversed()
sorted() devuelve una nueva lista ordenada sin modificar el original. reversed() devuelve un iterador. Úsalos para evitar modificar la colección original durante la iteración:
puntuaciones = [45, 92, 67, 88, 34, 71]
# sorted() no modifica la original
for p in sorted(puntuaciones, reverse=True):
print(p) # 92, 88, 71, 67, 45, 34
print(puntuaciones) # [45, 92, 67, 88, 34, 71] intacta
# reversed() para iterar al revés sin copiar
letras = ["a", "b", "c", "d"]
for l in reversed(letras):
print(l, end=" ") # d c b a
La regla: si necesitas el índice, usa enumerate(). Si iteras dos listas, usa zip(). Si recorres un dict, usa .items(). El acceso por índice manual es la forma más lenta y más propensa a errores de iterar en Python.
