El for loop en Python, en español “bucle for en Python”, se utiliza para ejecutar re­pe­ti­da­me­n­te un bloque de código. Los bucles for son una parte fu­n­da­me­n­tal de la mayoría de los lenguajes de pro­gra­ma­ción. A co­n­ti­nua­ción, te mostramos cómo funciona y cómo se utiliza el bucle for en Python.

Dominios web
Compra y registra tu dominio ideal
  • Domina el mercado con nuestra oferta 3x1 en dominios
  • Función Domain Connect para una co­n­fi­gu­ra­ción DNS si­m­pli­fi­ca­da gratis
  • Registro privado y gratis para mayor seguridad

¿Qué es el bucle for en Python?

Junto a la rama if else, el bucle for es pro­ba­ble­me­n­te la es­tru­c­tu­ra de pro­gra­ma­ción más conocida. Ge­ne­ra­cio­nes de es­tu­dia­n­tes se han exprimido el cerebro con el concepto in­fo­r­má­ti­co del bucle. Esto se debe a que, para empezar, los bucles no son muy in­tui­ti­vos. Sin embargo, los problemas de in­te­r­pre­ta­ción pueden surgir más bien de la forma en la que se presenta el material. Porque, si los ana­li­za­mos desde un punto de vista general, los bucles no son nada fuera de lo común.

Vamos a explicar el concepto de bucle con un ejemplo ilu­s­tra­ti­vo. Ima­gi­ne­mos una clase de colegio. El profesor quiere de­te­r­mi­nar la altura media de los niños como parte de un ex­pe­ri­me­n­to. Para ello, el profesor pregunta a cada niño su altura, uno por uno, y suma las tallas in­di­vi­dua­les para obtener un total. A co­n­ti­nua­ción, divide la suma entre el número de niños para obtener la altura media. Extraemos un sencillo algoritmo del pro­ce­di­mie­n­to que ha seguido el profesor:

  1. Preguntar la altura a cada niño y sumarla de forma co­n­se­cu­ti­va hasta obtener un total
  2. Dividir la suma entre el número de niños total

El primer paso se realiza una vez por cada niño y, por tanto, depende del tamaño de la clase. El segundo paso se ejecuta una sola vez, in­de­pe­n­die­n­te­me­n­te del tamaño de la clase. Ne­ce­si­ta­mos un bucle para llevar a cabo el primer paso. A co­n­ti­nua­ción, te mostramos un ejemplo de código que calcula el tamaño medio de un alumno con un bucle for en Python:

children_heights = [155, 171, 148, 161, 158, 153, 162]
height_sum = 0
for height in children_heights:
    height_sum = height_sum + height
average_height = height_sum // len(children_heights)
print(average_height)

El bucle for en Python ejecuta un bloque de código de forma re­pe­ti­ti­va, lo que también se puede denominar “iteración”. En pa­r­ti­cu­lar, los bucles permiten que varios elementos co­m­bi­na­dos en una misma “colección” sean pro­ce­sa­dos in­di­vi­dua­l­me­n­te según un mismo esquema. Uti­li­za­mos un bucle for cuando el tamaño de la colección puede de­te­r­mi­nar­se en el momento de ejecutar el programa. Si no es el caso, se suele utilizar un bucle while.

Consejo

En otro artículo de nuestra guía digital, podrás aprender Python por tu cuenta.

¿Qué di­fe­re­n­cia al bucle for en Python de otros lenguajes?

Muchos lenguajes de pro­gra­ma­ción conocen el concepto de bucle for. Además de Python, el bucle for también es una es­tru­c­tu­ra básica en otros lenguajes como C, Java, Ja­va­S­cri­pt y PHP. Los lenguajes fu­n­cio­na­les, como Haskell o Lisp, suelen arrie­s­gar­se a no tener un bucle for de manera explícita. En lugar de iterar, estos lenguajes utilizan funciones re­cu­r­si­vas.

Todos los bucles tienen en común que un bloque de código se ejecuta re­pe­ti­da­me­n­te. Sin embargo, el mecanismo de fu­n­cio­na­mie­n­to del bucle for en Python difiere si­g­ni­fi­ca­ti­va­me­n­te del de otros lenguajes. La mayoría de los lenguajes de pro­gra­ma­ción utilizan una variable de bucle que se in­cre­me­n­ta o disminuye cuando se ejecuta el bucle.

Operación Si­g­ni­fi­ca­do Sintaxis co­n­ve­n­cio­nal Sintaxis de Python
In­cre­me­n­to Aumenta el valor de una variable entera en una cantidad es­pe­cí­fi­ca y fija. i++ index += 1
Di­s­mi­nu­ción Disminuye el valor de una variable entera en una cantidad es­pe­cí­fi­ca y fija. i-- index -= 1

Veamos un ejemplo de cómo funciona un bucle for en otros lenguajes de código: pro­du­z­ca­mos los números del 0 al 9 en Ja­va­S­cri­pt con un bucle for. Solo debemos definir una variable entera llamada 'number' e in­cre­me­n­tar­la siempre que el número que contenga sea menor que 10. El código utilizado para ello parece bastante críptico para los pri­n­ci­pia­n­tes:

for ( let number = 0; number < 10; number++ ) {
    console.log(number);
}

El código re­s­pe­c­ti­vo de un bucle for en Python parece mucho más ordenado:

for number in range(10):
    print(number)

En lugar de emitir di­re­c­ta­me­n­te el valor de la variable del bucle, en la práctica este se suele utilizar para indexar un elemento dentro de una colección. De nuevo, empecemos primero con un ejemplo en Ja­va­S­cri­pt: se emiten los nombres co­n­te­ni­dos en la lista “personas” uno tras otro. Aquí uti­li­za­mos la variable de bucle 'i' como índice continuo de los elementos in­di­vi­dua­les:

people = ['Jack', 'Jim', 'John']
for (let i = 0; i < people.length; i++) {
    console.log("Here comes " + people[i]);
}

La in­de­xa­ción directa de elementos sucesivos de la lista debe tratarse con pre­cau­ción. Esto se debe a que un intento de acceso fuera de los límites pe­r­mi­ti­dos conduce a un error en el momento de la ejecución. Por lo general, se trata del famoso “Off-by-one Error”. Python, en cambio, demuestra que también se puede hacer de otra manera. Aquí tenemos el mismo ejemplo con un bucle for en Python: iteramos di­re­c­ta­me­n­te sobre los elementos de la lista con una variable de bucle sin in­de­xar­los:

people = ['Jack', 'Jim', 'John']
for person in people:
    print(f"Here comes {person}")

El uso indirecto de la variable de bucle co­n­tri­bu­ye mucho a confundir el apre­n­di­za­je de los bucles for en otros lenguajes. Esto se debe a que, por lo general, no nos interesa la variable del bucle que se encuentra en su interior. Pri­n­ci­pa­l­me­n­te, porque solo se utiliza para indexar los elementos in­di­vi­dua­les. Para utilizar los bucles for co­n­ve­n­cio­na­les es necesario co­m­pre­n­der varios aspectos complejos. Uti­li­za­n­do Ja­va­S­cri­pt como ejemplo:

Asunto Ocu­rre­n­cia en el bucle for de Ja­va­S­cri­pt
Asi­g­na­ción de variables let i = 0
Ex­pre­sio­nes booleanas i < limit
Operador de in­cre­me­n­to/di­s­mi­nu­ción i++ / i--
De­te­r­mi­nar el tamaño de una colección i < list.length
In­de­xa­ción de elementos a cero i < list.length ist OK; i <= list.length führt zu Off-by-one Error

El bucle for de Python es mucho más fácil de usar. Aunque se utiliza la misma palabra clave “for”, se trata de un enfoque ra­di­ca­l­me­n­te diferente. En lugar de in­cre­me­n­tar una variable de bucle y así indexar su­ce­si­va­me­n­te los elementos, iteramos di­re­c­ta­me­n­te sobre los elementos de una colección. El bucle for en Python es, por tanto, co­m­pa­ra­ble a la es­tru­c­tu­ra forEach de algunos lenguajes como Ruby y Ja­va­S­cri­pt.

Vamos a emitir las letras in­di­vi­dua­les de una palabra a modo de ilu­s­tra­ción. Dentro del bucle for, una letra de la palabra se pone a di­s­po­si­ción de la variable 'letter' por cada pasada del bucle. Esto funciona sin una variable de bucle y, por lo tanto, sin el riesgo de producir un Off-by-one Error. El código es preciso y fácil de leer:

word = "Python"
for letter in word:
    print(letter)

¿Cómo funciona un bucle for en Python?

Como hemos visto, el bucle for en Python resuelve de forma elegante el problema de iterar sobre los elementos de una colección. Nos permite hacerlo sin los desvíos que implica una variable de bucle numérica. Eso está muy bien, pero ¿cómo funciona exac­ta­me­n­te? Para entender el principio de fu­n­cio­na­mie­n­to del bucle for en Python, primero es necesario conocer los conceptos de iterable e iterador.

¿Qué es el iterable, el iterador y el generador?

El bucle for en Python opera sobre objetos conocidos como “iterables”. Se trata de strings, listas, tuplas y otros tipos de datos co­m­pue­s­tos. En palabras de los do­cu­me­n­tos oficiales de Python:

Cita

“[An iterable is] an object capable of returning its members one at a time” - Fuente: https://docs.python.org/3/glossary.html#term-iterable

Tra­du­c­ción: “[Un iterable es] un objeto capaz de retornar sus miembros de uno en uno” (traducido por IONOS)

Un objeto iterable tiene dos pro­pie­da­des:

  1. Combina varios elementos en una colección.
  2. Permite el acceso a los elementos a través de una interfaz llamada “iterador”.

En conjunto, esto significa que los iterables son co­le­c­cio­nes cuyo contenido puede ser iterado. En concreto, un iterable tiene un método '__iter__()' que devuelve un iterador. El iterador es un objeto que, con el debido comando, retorna el siguiente elemento del iterable. Además, un iterador recuerda la posición del último elemento devuelto dentro de la colección.

Función Ex­pli­ca­ción Ejemplo
iter(co­lle­c­tion) Llama al método __iter__() de la colección it = iter("Python")
next(iter) Llama al método __next__() del iterator next(it)
co­lle­c­tion[index] Llama al método __getitem__(index) de la colección 'Python'[1]

Un iterador retorna el siguiente elemento cuando se llama al método __next__(). Si se han entregado todos los elementos de la colección, el iterador se agota. Otra llamada a __next__() genera una excepción 'S­to­pI­te­ra­tio­n'.

Veamos el fu­n­cio­na­mie­n­to de un iterador a través de un ejemplo. Creamos un objeto range() que re­pre­se­n­ta los números co­n­se­cu­ti­vos del 21 al 23. Po­s­te­rio­r­me­n­te, creamos un iterador con la función iter() y emitimos su­ce­si­va­me­n­te elementos con la función next(). Con la última llamada, se lanza la excepción puesto que el iterador se ha agotado:

numbers = range(21, 24)
number = iter(numbers)
next(number)
# returns `21`
next(number)
# returns `22`
next(number)
# returns `23`
next(number)
# raises `StopIteration` exception

Un iterador permite acceder a elementos in­di­vi­dua­les de una colección. Python también conoce un concepto semejante conocido como “generador”. La di­fe­re­n­cia es que un generador crea elementos in­di­vi­dua­les solo cuando se accede a ellos. Esto ahorra espacio de memoria durante la ejecución del programa; también se denomina “lazy ge­ne­ra­tion”.

Un generador en Python se basa en una función que utiliza la sentencia yield. Al igual que la sentencia return, devuelve un objeto y finaliza la función. Sin embargo, cuando se activa nue­va­me­n­te, la función generador no empieza desde el principio, sino que continúa a partir de la última sentencia yield.

Veamos un ejemplo: re­da­c­te­mos nuestra propia im­ple­me­n­ta­ción de la función range(). Uti­li­za­mos, para ello, la sentencia yield dentro de un bucle while para generar números continuos:

def my_range(start, stop):
    if stop < start:
        return None
    current = start
    while current < stop:
        yield current
        current += 1
# test
assert list(my_range(7, 9)) == list(range(7, 9))

Saltar y cancelar la ejecución del bucle for en Python

En la práctica, a veces es necesario saltarse una sola pasada de bucle. Como muchos otros lenguajes, Python dispone de la sentencia continue. Cuando se ejecuta un continue dentro del cuerpo del bucle, se aborta la iteración actual e inicia in­me­dia­ta­me­n­te la siguiente iteración.

Una sentencia continue puede uti­li­zar­se de forma similar al early return mientas se ejecuta una función. Por ejemplo, después de de­te­r­mi­nar que un conjunto de datos no tienes la calidad requerida, vamos a saltarnos una iteración:

def process_data(data):
    for data_set in data:
        data_set.validate()
        # early continue after cheap check fails
        if not data_set.quality_ok():
            continue
        # expensive operation guarded by early continue
        data_set.process()

Otro ejemplo: emitimos un texto y saltamos cada dos letras:

text = 'Skipping every second letter'
for index, letter in enumerate(text):
    if index % 2 != 0 and letter != ' ':
        continue
    print(letter)

Además de la sentencia continue para saltarse una pasada del bucle, también existe la sentencia break. Ejecutar un break dentro del cuerpo del bucle aborta in­me­dia­ta­me­n­te la ejecución de este. Así pues, la sentencia break tiene una función en los bucles parecida a la de la sentencia return en las funciones.

La sentencia break se utiliza a menudo para im­ple­me­n­tar al­go­ri­t­mos de búsqueda. Una vez que se haya en­co­n­tra­do el elemento re­s­pe­c­ti­vo dentro de un bucle, no es necesario seguir iterando. De forma análoga a la función any(), co­m­pro­ba­mos la presencia de un único valor true en la lista y, en cuanto en­co­n­tra­mos algo, rompemos el proceso con la sentencia break:

bool_list = [False, False, True, False]
for index, boolean in enumerate(bool_list):
    if boolean:
        print(f"Value at position {index + 1} is True")
        print(f"Aborting inspection of remaining {len(bool_list) - index - 1} item(s)")
        break

En relación con la sentencia break, un bucle for en Python puede estar provisto de una sentencia else opcional. El código que contiene se ejecuta cuando el bucle termina sin que se haya ejecutado una sentencia break:

def find_element(target, collection):
    for element in collection:
        if element == target:
            print("Found what you're looking for")
            break
    else:
        print("Didn't find what you were looking for")
# test
find_element('a', 'Python')
find_element('o', 'Python')

Los bucles for se utilizan a menudo en Python dentro de los cuerpos de las funciones. En este caso, es habitual utilizar una sentencia return en lugar de un break. Volvemos a formular nuestro algoritmo de búsqueda sin el uso de break y else:

def find_element(target, collection):
    for element in collection:
        if element == target:
            print("Found what you're looking for")
            # returning breaks us out of the loop
            return element
    # we made it here without returning
    print("Didn't find what you were looking for")
    return None
# test
print(find_element('a', 'Python'))
print(find_element('o', 'Python'))

¿Cuáles son las mejores prácticas para los bucles for en Python?

Los bucles for en Python se utilizan pri­n­ci­pa­l­me­n­te para iterar sobre los elementos de una secuencia o colección. Además, existen métodos más directos para muchos casos de uso común. A co­n­ti­nua­ción, pre­se­n­ta­mos las mejores prácticas y los an­ti­pa­tro­nes más im­po­r­ta­n­tes. En primer lugar, un resumen de los pri­n­ci­pa­les términos:

Término Ex­pli­ca­ción Ejemplo
Colección Colección de varios elementos. Una colección es un iterable ('Walter', 'White'), [4, 2, 6, 9], 'Python'
Iterador Interfaz para iterar sobre co­le­c­cio­nes it = iter('Python')
Generador Una función que utiliza la sentencia yield en lugar de return. Un generador es un iterable range(10)
Co­m­pre­n­sión Expresión de iteración; crea una nueva colección basada en un iterable [num ** 2 for num in range(10)]

Iterar di­re­c­ta­me­n­te sobre los elementos de una colección

Un error común que cometen los pro­gra­ma­do­res de Python sin ex­pe­rie­n­cia es el mal uso del bucle for en Python. Como es común en otros lenguajes, utilizan la función len() como límite de la función range() para crear una variable numérica de bucle. La utilizan para indexar los elementos in­di­vi­dua­les de la colección:

word = 'Python'
for i in range(len(word)):
    print(word[i])

Este an­ti­pa­trón se critica con razón por no ser co­m­pa­ti­ble con Python y es mejor iterar di­re­c­ta­me­n­te sobre los elementos de la colección mediante el bucle for de Python:

word = 'Python'
for letter in word:
    print(letter)

Enumerar elementos de una colección con enumerate() incluido el índice

A veces se necesita el índice de un elemento dentro de la colección. En lugar de crear el índice como una variable de bucle, uti­li­za­mos la función enumerate(). Esta devuelve la tupla (índice, elemento), aunque debes tener en cuenta que el índice empieza a contar desde cero:

names = ["Jim", "Jack", "John"]
for index, name in enumerate(names):
    print(f"{index + 1}. {name}")

Iterar sobre tuplas de elementos con la función zip()

Otro escenario común es iterar sobre los elementos de dos co­le­c­cio­nes de igual longitud al mismo tiempo. El enfoque de Python utiliza la función zip(). Toma dos co­le­c­cio­nes de igual longitud y devuelve 2 tuplas sucesivas:

people = ('Jim', 'Jack', 'John')
ages = (42, 69, 13)
# ascertain both collections are same length
assert len(people) == len(ages)
# iterate over tuples of (person, age)
for person, age in zip(people, ages):
    print(f"{person} is {age} years old")

Crear una variable de bucle numérica con la función range()

No­r­ma­l­me­n­te, los bucles for en Python se utilizan para iterar sobre los elementos de una colección. Utilizar un bucle for en Python para in­cre­me­n­tar un número entero es algo poco usual. La mejor manera de hacerlo es co­n­s­tru­ye­n­do un objeto range con la función range() e iterar sobre él:

for counter in range(10):
    print(counter)

Uso del operador in para comprobar si una colección contiene un elemento

Encontrar un elemento es­pe­cí­fi­co dentro de una colección forma parte del re­pe­r­to­rio estándar de un pro­gra­ma­dor. No­r­ma­l­me­n­te, se utiliza una función que itera sobre los elementos, co­m­pro­ba­n­do la semejanza de cada elemento con el que se busca. Si se encuentra el elemento deseado, se aborta la iteración.

En Python, el operador in existe para este caso tan habitual. Este operador comprueba si la colección contiene el elemento buscado y devuelve el valor booleano co­rre­s­po­n­die­n­te:

'a' in 'Python'
'y' in 'Python'

Crear una lista a partir de un iterable con la función list()

A di­fe­re­n­cia de muchos otros lenguajes, en Python no es necesario utilizar un bucle for para escribir las letras de un string una a una en una lista. En su lugar, uti­li­za­mos la función list() para convertir un iterable en una lista de elementos. Veamos ambos enfoques con un ejemplo. Iteramos sobre las letras de una palabra y las añadimos a una lista vacía:

word = 'Python'
letters = []
for letter in word:
	letters.append(letter)
apa­che­co­nf

Podemos aho­rrar­nos el esfuerzo. Creamos la lista di­re­c­ta­me­n­te con la función list(). Al mismo tiempo, co­m­pro­ba­mos con la sentencia assert que ambos métodos dan el mismo resultado:

assert list(word) == letters
apa­che­co­nf

Otro ejemplo: creamos una lista de números del cero al nueve y un objeto range sirve de base como iterable:

list(range(10))
apa­che­co­nf

Además de las listas, también se pueden crear conjuntos o “sets” (en inglés) a partir de un iterable. Por ejemplo, creamos un conjunto que refleja las letras co­n­te­ni­das en una frase. A co­n­ti­nua­ción, co­m­pro­ba­mos con el operador in que el conjunto de letras no contiene la 'a':

alphabet = set('Python is not hyped')
assert 'a' not in alphabet
apa­che­co­nf

Sustituir los bucles for en Python por co­m­pre­n­sio­nes

Un uso común de los bucles for en Python es el de modificar los elementos de una colección. Se puede utilizar cuando queremos calcular nuevos valores en base a una colección o filtrar ciertos elementos según un patrón. Siguiendo el estilo de pro­gra­ma­ción im­pe­ra­ti­va, de­s­cri­bi­mos los pasos in­di­vi­dua­les:

  1. Iterar sobre la colección con el bucle for.
  2. Procesar cada elemento.
  3. Si es necesario, combinar un su­b­co­n­ju­n­to de elementos en una nueva colección.

Para realizar mo­di­fi­ca­cio­nes sencillas, esto resulta demasiado complejo. Los lenguajes fu­n­cio­na­les de­mue­s­tran que se puede hacer de forma más fácil. Afo­r­tu­na­da­me­n­te, Python cuenta con el concepto de “co­m­prehe­n­sio­ns” (co­m­pre­n­sio­nes). Las co­m­pre­n­sio­nes pueden re­em­pla­zar apli­ca­cio­nes simples del bucle for en Python y, de hecho, son más eficaces que las apli­ca­cio­nes equi­va­le­n­tes de un bucle for.

Una co­m­pre­n­sión crea una colección, que puede estar adaptada y basada en un iterable en caso de que sea necesario. Esta utiliza una sintaxis concisa y expresiva. A co­n­ti­nua­ción, un ejemplo de la sintaxis general de la co­m­pre­n­sión de una lista, donde la expresión está escrita entre corchetes y la operación se realiza sobre los elementos de una colección; cada elemento se copia en una nueva lista:

[ operation(element) for element in collection ]
apa­che­co­nf

Además, los elementos pueden filtrarse según de­te­r­mi­na­dos patrones. Se utiliza un if opcional y una condición:

[ operation(element) for element in collection if condition(element) ]
apa­che­co­nf

Veamos ahora un ejemplo de bucle for en Python que se puede sustituir por una co­m­pre­n­sión. Tenemos una lista de números y queremos calcular una lista equi­va­le­n­te con los cuadrados de los números de la primera lista:

numbers = [2, 3, 5, 9, 17]
apa­che­co­nf

Creamos una lista vacía e in­tro­du­ci­mos un bucle if que contiene el cálculo de los cuadrados de los números en su interior:

squares = []
for number in numbers:
	squares.append(number ** 2)
apa­che­co­nf

La lista de números cuadrados puede ex­pre­sar­se de forma más sencilla en forma de una lista de co­m­pre­n­sión:

squares_comp = [number ** 2 for number in numbers]
apa­che­co­nf

A co­n­ti­nua­ción, uti­li­za­mos la sentencia assert para ase­gu­rar­nos de que ambos métodos arrojan el mismo resultado:

assert squares == squares_comp
apa­che­co­nf

Otro ejemplo: si queremos extraer las letras mi­nú­s­cu­las de un string, debemos crear e in­tro­du­cir como entrada una lista con una co­m­bi­na­ción de letras ma­yú­s­cu­las y mi­nú­s­cu­las:

word = list("PyThoN")
apa­che­co­nf

La forma co­n­ve­n­cio­nal de extraer las mi­nú­s­cu­las es iterar sobre las letras. Durante ese proceso probamos cada letra con la función islower() y, en caso de tener un resultado positivo, las añadimos a una lista ini­cia­l­me­n­te vacía:

lowers = []
for letter in word:
	if letter.islower():
		lowers.append(letter)
apa­che­co­nf

El bucle for nos lo podemos ahorrar con Python. En su lugar, uti­li­za­mos una co­m­pre­n­sión que solo copia las letras mi­nú­s­cu­las de la lista original:

lowers_comp = [ letter for letter in word if letter.islower() ]
apa­che­co­nf

De nuevo, co­m­pro­ba­mos que ambos métodos arrojan el mismo resultado mediante la sentencia assert:

assert lowers == lowers_comp
apa­che­co­nf
Ir al menú principal