Una lista en Python es una secuencia ordenada y mutable que puede contener cualquier tipo de dato. Recorrer sus elementos es una de las operaciones más habituales en cualquier programa, y Python ofrece varias formas de hacerlo, cada una con sus ventajas según el contexto. Este artículo cubre las técnicas principales con ejemplos en Python 3.
Definir una lista
Antes de iterar, necesitas una lista. Se define con corchetes y los elementos separados por comas:
signos = [
"aries", "tauro", "géminis", "cáncer", "leo", "virgo",
"libra", "escorpio", "sagitario", "capricornio", "acuario", "piscis"
]
En Python 3, print es una función, así que siempre lleva paréntesis. Los ejemplos anteriores a 2015 que verás por internet con print "texto" son Python 2, que lleva años sin mantenimiento.
El bucle for: la forma más directa
El bucle for de Python no necesita índice. En cada iteración la variable toma el valor del elemento actual:
for signo in signos:
print(signo)
aries tauro géminis ...
El nombre de la variable (signo) es libre. Usar un nombre descriptivo en singular cuando la lista está en plural hace el código más legible sin ningún coste adicional.
enumerate(): índice y valor a la vez
Cuando necesitas el índice además del valor, enumerate() evita tener que mantener un contador manual:
for i, signo in enumerate(signos):
print(f"{i + 1}. {signo}")
1. aries 2. tauro 3. géminis ...
Puedes indicar desde qué número empieza el índice con el segundo argumento:
for i, signo in enumerate(signos, start=1):
print(f"{i}. {signo}")
La alternativa con range(len(lista)) funciona pero es más verbosa y menos idiomática:
# Funciona, pero enumerate() es más limpio
for i in range(len(signos)):
print(f"{i}. {signos[i]}")
Comprensiones de lista: transformar mientras iteras
Las list comprehensions son la forma más Pythónica de aplicar una operación a cada elemento y obtener una nueva lista en una sola línea:
# Convertir todos los elementos a mayúsculas mayusculas = [signo.upper() for signo in signos] print(mayusculas) # ['ARIES', 'TAURO', 'GÉMINIS', ...]
También admiten una condición de filtro:
# Solo los signos con más de 5 caracteres largos = [signo for signo in signos if len(signo) > 5] print(largos) # ['géminis', 'virgo', 'libra', 'escorpio', 'sagitario', 'capricornio', 'acuario', 'piscis']
Si no necesitas la lista resultante sino solo iterar para imprimir o ejecutar un efecto, usa un for normal. Las comprensiones están pensadas para producir una colección nueva.
zip(): iterar dos listas en paralelo
Cuando tienes dos listas relacionadas y quieres recorrerlas a la vez, zip() las empareja elemento a elemento:
signos = ["aries", "tauro", "géminis"]
elementos = ["fuego", "tierra", "aire"]
for signo, elemento in zip(signos, elementos):
print(f"{signo.capitalize()} ? {elemento}")
Aries ? fuego Tauro ? tierra Géminis ? aire
Si las listas tienen distinta longitud, zip() se detiene en la más corta. Para seguir hasta la más larga rellenando con un valor por defecto, usa itertools.zip_longest().
El bucle while con índice
El while tiene sentido cuando la condición de parada no es «llegar al final de la lista» sino algo más complejo, como buscar un elemento o procesar hasta que se cumpla cierta condición:
i = 0
while i < len(signos) and signos[i] != "leo":
print(signos[i])
i += 1
print(f"Encontrado en posición {i}: {signos[i]}")
Para recorridos lineales sin condición especial, el for siempre es más claro.
map() y filter(): el estilo funcional
map() aplica una función a cada elemento de la lista y devuelve un iterador:
mayusculas = list(map(str.upper, signos)) print(mayusculas)
filter() selecciona los elementos que cumplen una condición:
largos = list(filter(lambda s: len(s) > 5, signos)) print(largos)
En Python moderno las comprensiones de lista suelen ser más legibles que map() y filter() para casos sencillos. Estas funciones brillan cuando trabajas con funciones ya definidas o encadenas transformaciones en pipelines de datos.
Generadores: iterar sin cargar todo en memoria
Si la lista es muy grande o los datos se generan al vuelo, un generador procesa un elemento a la vez sin construir la colección completa en memoria. La sintaxis es igual que una comprensión de lista pero con paréntesis en lugar de corchetes:
# Comprensión de lista: crea toda la lista en memoria
cuadrados_lista = [x**2 for x in range(1_000_000)]
# Expresión generadora: produce un valor cada vez que se pide
cuadrados_gen = (x**2 for x in range(1_000_000))
for valor in cuadrados_gen:
print(valor)
if valor > 100:
break # podemos parar sin haber generado el resto
Para listas pequeñas la diferencia es irrelevante. Cuando el volumen de datos crece, los generadores evitan picos de uso de memoria.
Cuándo usar cada técnica
Técnica |
Cuándo usarla |
| Recorrido simple sin necesitar el índice |
| Necesitas índice y valor a la vez |
Comprensión de lista | Transformar o filtrar para obtener una lista nueva |
| Recorrer dos o más listas en paralelo |
| Condición de parada que no es «fin de lista» |
| Pipelines funcionales o funciones ya definidas |
Expresión generadora | Volumen grande de datos, procesar de uno en uno |
Si quieres profundizar en el ecosistema de Python más allá de los fundamentos, el artículo sobre Python en 2025: mejoras de rendimiento y librerías nuevas cubre las novedades más relevantes del lenguaje en los últimos ciclos. Y si necesitas controlar el tiempo de ejecución de tus bucles, el artículo sobre Python time.sleep() explica cómo añadir pausas de forma controlada. Para aplicaciones más ambiciosas, automatización de tareas repetitivas con Python y RPA muestra cómo poner en práctica estas técnicas en scripts reales.
