El bucle FOR

El bucle FOR

Como se mencionó anteriormente, la instrucción de repetición FOR se usa principalmente en Python para iterar o recorrer una variable tipo secuencial como una tupla, lista, rango, etc. 

La sintaxis básica de un bucle FOR es como sigue:

FOR <variable entera> IN <variable iterable>:
En este bloque de código se escriben las instrucciones que se van a repetir tantas veces como elementos hayan en la tupla, es importante que este debidamente sangrado,

Aunque se verán luego con mas detalles los tipos de variables en Python, de momento vale decir que una variable tipo TUPLA es una colección de valores inmutables. Por ejemplo los días de la semana, los meses del año, etc. 

Veamos un un primer ejemplo sencillo de un bucle que recorre una lista simple de 3 números:

for i in (1,2,3):
    print(i)

Resultado:

1
2
3

Los bucles for en Python funcionan de tal forma que al llegar el flujo de ejecución del programa a la instrucción FOR le asigna a la variable declarada, en el ejemplo anterior sería a la variable i, el valor del primer elemento del objeto iterable, que en nuestro ejemplo sería de la lista (1,2,3) el entero 1. Luego procede a ejecutar la instrucción o instrucciones del cuerpo del bucle, que en el ejemplo anterior es solamente mostrar por pantalla el valor de i. Esto se repite hasta llegar al final de la lista (1,2,3) con lo cual el valor de i va a ir cambiando cada vez ya que i es la variable contadora del ciclo, por lo que el resultado por pantalla va a ser 1 2 y 3 como se pudo comprobar al ejecutar el programa.

Como se puede comprobar el bucle FOR realiza el recorrido de la lista imprimiendo cada elemento encontrado en ella, en este caso es un bucle finito determinado por la cantidad de elementos que componen la lista.

Si desearíamos crear un ciclo mas grande que no tenga nada que ver con el contenido de un elemento iterable, por ejemplo que quisiéramos mostrar por pantalla un mensaje n cantidad de veces sin que tuviera algo que ver con ningún objeto iterable. Para ello podemos recurrir a la instrucción RANGE(), en donde se definirá un valor inicial de 1 y un valor final que ingresará el usuario por teclado. Hay que recordar que la función RANGE() devuelve un objeto tipo rango desde el valor inicial hasta 1 menos el valor final, con lo cual conviene sumarle 1 a la variable contadora del ciclo. Veamos el siguiente ejemplo:


j=int(input('Introduzca la cantidad de veces que desea repetir el ciclo: '))

for i in range(1,j+1):
    print(f'{i} Felicidades')

Resultado:

Introduzca la cantidad de veces que desea repetir el ciclo: 10
1 Felicidades
2 Felicidades
3 Felicidades
4 Felicidades
5 Felicidades
6 Felicidades
7 Felicidades
8 Felicidades
9 Felicidades
10 Felicidades

Como podemos ver el programa esa haciendo lo que se esperaba de acuerdo al planteamiento original. Esto es muy parecido al uso del bucle FOR en otros lenguajes de programación.

Es posible especificar el rango diferente en un tipo de dato range, indicando el valor de inicio y el de fin de la siguiente manera:

for i in range(5,10):
    print(i)

Resultado:

5
6
7
8
9

Como se puede ver ahora el rango es del 5 inclusive al 9, recordemos que el límite superior no se cuenta a la hora de ejecutar la operación ya que queda excluído al salirse del bucle cuando se cumple la condición (en este caso i=10).

Si la función RANGE() solo recibe un argumento, por defecto asume que el rango empieza en cero (0) y el argumento recibido es el límite superior, veamos el siguiente ejemplo:

for i in range(5):
    print(i)

Resultado:

0
1
2
3
4

Como se esperaba la función RANGE() toma el único argumento que recibe como el límite superior asumiendo que debe comenzar el rango en cero (0).

Otro argumento que admite la función RANGE() es el de paso o step en inglés, lo que significa de cuanto es el salto de un número a otro. Por defecto es uno, o sea que va incrementando el valor de uno en uno, pero se puede hacer de dos en dos, de tres en tres, de n en n, definiendo n como tercer argumento. Veamos el siguiente ejemplo:

for i in range(1,30,5):
    print(i)

Resultado:

1
6
11
16
21
26

Como se esperaba se muestra un rango de números desde el uno hasta el 30 (sin mostrar el último como ya sabemos) pero esta vez saltando de 5 en 5 como se especificó en el último argumento de la llamada a la función RANGE().

Otro ejemplo para ver mas posibilidades:

for i in range(1,22,7):
    print(i)

Resultado:

1
8
15

Vamos a valernos ahora de una variable tipo tupla para ejemplificar el uso del bucle FOR:

tupDiasSemana="Lunes","Martes","Miércoles","Jueves","Viernes","Sábado","Domingo"
for x in tupDiasSemana:
    print(x)
 
El código anterior arroja como resultado:

Lunes
Martes
Miércoles
Jueves
Viernes
Sábado
Domingo

Como podemos ver el bucle FOR recorre el objeto tupDiasSemana elemento por elemento de manera secuencial siin necesidad de usar una variable para el índice que se incremente en uno cada vez que se ejecute el bloque de código. Los programadores con experiencia en otros lenguajes de programación saben bien lo que es esto. No tener que definir una variable e incrementarla en una unidad para recorrer una colección dentro de un objeto iterable de manera secuencial ascendente, pudiera parecer en principio una limitación, sin embargo y siendo honestos como desarrolladores de software, éste es el caso en la inmensa mayoría de las veces al iterar secuencialmente un objeto de este tipo.

El bucle FOR funciona de la misma manera en una cadena de texto, recorriendo cada uno de los caracteres que la conforman de manera secuencial ascendente. Veamos el siguiente ejemplo:

for x in "Esta es una cadena de texto para iterar":
    print(x)
quit()

El código anterior arroja el siguiente resultado:

E
s
t
a

e
s

u
n
a

c
a
d
e
n
a

d
e

t
e
x
t
o

p
a
E
s
t
a

e
s

u
n
a

c
a
d
e
n
a

d
e

t
e
x
t
o

E
s
t
a

e
s

u
n
a

c
a
d
e
n
a

d
e

t
e
x
t
o

p
a
r
a

i
t
e
r
a
r

Para ilustrar mejor la belleza y elegancia de la instrucción FOR en Python, hagamos las mismas pruebas hechas con el FOR pero esta vez con un bucle WHILE para comparar.

Usando un cliclo WHILE el código quedaría de la sigiuente manera:

tupDiasSemana="Lunes","Martes","Miércoles","Jueves","Viernes","Sábado","Domingo"
x=0
while x < len(tupDiasSemana):
    print(tupDiasSemana[x])
    x=x+1

con el uso del bucle FOR sería:

tupDiasSemana="Lunes","Martes","Miércoles","Jueves","Viernes","Sábado","Domingo"
for x in tupDiasSemana:
    print(x)

ambos arrojan el mismo resultado:

Lunes
Martes
Miércoles
Jueves
Viernes
Sábado
Domingo

Hay que mencionar que en este código se muestra la función incorporada LEN(), la cual devuelve un entero con el valor de la cantidad de caracteres que componen la cadena pasada como argumento.

Ya resultan obvias las ventajas de usar un bucle FOR en lugar de un bucle WHILE incluso en un código tan simple como el anterior, menos lineas de código, menos variables que iniciar para luego incrementar. Incluso no hay siquiera necesidad de establecer la condición de salida del bucle WHILE x < len(tupDiasSemana), ya que la misma instrucción FOR entiende que se termina el bucle al acceder al último elemento de la colección de datos del objeto iterable. Esto por supuesto redunda en menos código, mejor legibilidad, menos errores de sintaxis y lógicos; lo cual se agradece en un programa de una complejidad mayor.

Aplicación práctica

Supongamos que necesitamos crear un programa que valide la dirección de email ingresada por el usuario, bastaría con recorrer la cadena que ingrese el usuario caracter a caracter y hacer ciertas validaciones, veamos el ejemplo de como podría plantearse la solución. Es importante destacar que el código se puede mejorar aun más pero de momento se va a dejar solo con las funciones básicas para ilustrar el uso de ciclos repetitivos.

Si se usa un bucle FOR en combinación con una cadena de caracteres lo que sucederá es que el bucle se ejecutará tantas veces como caracteres hayan en la cadena. Una aplicación práctica y útil de esta característica podría ser por ejemplo la verificación del ingreso correcto de una dirección de correo electrónico, en donde hay que verificar que se haya ingresado el caracter arroba (@) dentro del texto y que no puede estar como primer elemento ni antes del punto (.) del nombre de dominio del email y por supuesto tiene que haber un punto para especificar el nombre del dominio, por ejemplo cesargamboa13@hotmail.com es un email válido mientras que @cesargamboa13hotmail.com no lo sería, al igual que cesargamboa13hotmail tampoco es un email válido. Veamos la aplicación práctica de lo dicho anteriormente:


print('*** Programa de validación de email ***\n')
email_usuario = input('Ingrese su email: ')
i=0
bValido = True
bContieneArroba=False
bContienePunto=False
bExcesoArrobas=False

for s in email_usuario:
    if i==0 and s=='@':
        print('Error: email no puede comenzar con arroba (@)')
        bValido=False
    if i==0 and s=='.':
        print('Error: email no puede comenzar con punto (.)')
        bValido=False
    if s=='@' and not bContieneArroba:
        bContieneArroba=True
    elif s=='@' and bContieneArroba:
        bExcesoArrobas=True
    if s=='.':bContienePunto=True
    if i==len(email_usuario)-1 and s=='@':
        print('Error: email no puede terminar con arroba (@)')
        bValido=False
    if i==len(email_usuario)-1 and s=='.':
        print('Error: email no puede terminar con punto (.)')
        bValido=False
    i=i+1


if not bContieneArroba:
    print('Error: email no contiene arroba @')
    bValido = False
if not bContienePunto:
    print('Error: email no contiene punto .')
    bValido=False
if bExcesoArrobas:
    print('Error: email debe contener un solo arroba @')
    bValido=False
print('\n')

if bValido:
    print(f'''\nLa dirección de email {email_usuario}
es válida, puede usarla''')
else:
    print(f'''\nLa dirección de email {email_usuario}
NO es válida, cámbiela por favor''')

Resultado ingresando cesargamboa13@hotmail.com:

*** Programa de validación de email ***

Ingrese su email: cesargamboa13@hotmail.com



La dirección de email cesargamboa13@hotmail.com
es válida, puede usarla


Resultado ingresando @cesargamboa13hotmail.com:

*** Programa de validación de email ***

Ingrese su email: @cesargamboa13hotmail.com
Error: email no puede comenzar con arroba (@)



La dirección de email @cesargamboahotmail.com
NO es válida, cámbiela por favor

Resultado ingresando .cesargamboa13@hotmail.com:

*** Programa de validación de email ***

Ingrese su email: .cesargamboa@hotmail.com
Error: email no puede comenzar con punto (.)



La dirección de email .cesargamboa13@hotmail.com
NO es válida, cámbiela por favor

Resultado ingresando cesargamboa@13@hotmail.com:

*** Programa de validación de email ***

Ingrese su email: cesargamboa@13@hotmail.com
Error: email debe contener un solo arroba @



La dirección de email cesargamboa@13@hotmail.com
NO es válida, cámbiela por favor

Nota: las condiciones de evaluación del email no deben tomarse como estándar de direcciones correctas de email, son solamente para ejemplificar el uso del bucle FOR.


Nota: Para mas información relacionada a la función LEN() puede ver funciones incorporadas en Python.

Ahora veamos como quedaría el programa de validación de emails pero usando la función LEN() evitando así el uso de un contador i.

print('*** Programa de validación de email usando range()***\n')
email_usuario = input('Ingrese su email: ')
bValido = True
bContieneArroba=False
bContienePunto=False
bExcesoArrobas=False

for i in range(len(email_usuario)):
    if i==0 and email_usuario[i]=='@':
        print('Error: email no puede comenzar con arroba (@)')
        bValido=False
    if i==0 and email_usuario[i]=='.':
        print('Error: email no puede comenzar con punto (.)')
        bValido=False
    if email_usuario[i]=='@' and not bContieneArroba:
        bContieneArroba=True
    elif email_usuario[i]=='@' and bContieneArroba:
        bExcesoArrobas=True
    if email_usuario[i]=='.':bContienePunto=True
    if i==len(email_usuario)-1 and email_usuario[i]=='@':
        print('Error: email no puede terminar con arroba (@)')
        bValido=False
    if i==len(email_usuario)-1 and email_usuario[i]=='.':
        print('Error: email no puede terminar con punto (.)')
        bValido=False

if not bContieneArroba:
    print('Error: email no contiene arroba @')
    bValido = False
if not bContienePunto:
    print('Error: email no contiene punto .')
    bValido=False
if bExcesoArrobas:
    print('Error: email debe contener un solo arroba @')
    bValido=False
print('\n')

if bValido:
    print(f'''\nLa dirección de email {email_usuario}
es válida, puede usarla''')
else:
    print(f'''\nLa dirección de email {email_usuario}
NO es válida, cámbiela por favor''')

Resultado ingresando cesargamboa13hotmail.com:

*** Programa de validación de email usando range()***

Ingrese su email: cesargamboa13hotmail.com
Error: email no contiene arroba @



La dirección de email cesargamboa13hotmail.com
NO es válida, cámbiela por favor

Resultado ingresando .cesargamboa13@hotmail.com:

*** Programa de validación de email usando range()***

Ingrese su email: .cesargamboa13@hotmail.com
Error: email no puede comenzar con punto (.)

Resultado ingrersando cesargamboa13@hotmail.com:

*** Programa de validación de email usando range()***

Ingrese su email: cesargamboa13@hotmail.com



La dirección de email cesargamboa13@hotmail.com
es válida, puede usarla

Como podemos comprobar con algunos ejemplos para forzar el error y otro con el email correcto, podemos comprobar que el programa esta realizando su tarea correctamente como se esperaba.

Otros usos del bucle FOR


Además de iterar objetos que contengan colecciones, existe otro uso muy común del bucle FOR, el de repetir una cantidad determinada de veces que se realiza un bloque de código sin hacer referencia a ningún objeto iterable o recorrer ninguna variable para leer su contenido. Para esto nos vamos a valer de la función RANGE, la cual devuelve una secuencia de números, empezando por 0 por defecto e incrementándose en 1 por defecto. En el apartado de funciones incorporadas de Python veremos mas detallado su uso, de momento esa información nos vale para ejemplificar del bucle FOR. Su sintaxis básica es como sigue: RANGE(n), que usada de esta manera devuelte una secuencia de números desde 0 hasta n. Si se combina con un bucle FOR podemos repetir n bloque de código n veces independientemente de lo que suceda dentro del bucle. Por ejemplo consideremos el siguiente código:

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

El código anterior arroja el siguiente resultado:

0
1
2
3
4
5
6
7
8
9

Como era de esperarse, la función RANGE(10) devuelve una secuencia números de manera ascendente iniciando desde el 0 hasta llegar al 9, para un total de 10 elementos como se le especificó en el argumento de la fución. Ahora bien; en este caso, el bucle FOR repite 10 veces el bloque de código perteneciente al ámbito que abarca, lo que es solamente imprimir el elemento recorrido en el rango generado por la función RANGE. Como se puede observar puede ser que se necesite ejecutar un bloque de código n cantidad de veces, sin contar necesariamente con un objeto iterable previamente. Es por ello que es necesario hacerse de un objeto iterable que sirva de apoyo para lograr este objetivo, es aquí donde destaca la utilidad de la función RANGE() creando un objeto iterable perteneciente a la clase rango en combinación con el bucle FOR.

Un aspecto importante a tomar en cuenta en el uso de un bucle FOR en combinación de la instrucción PRINT(), es que PRINT() muestra por pantalla el mensaje entre comillas y hace por defecto un salto de línea, como se pudo ver en el ejemplo anterior. Pudiera ser el caso que se desee que luego de imprimir el dato por pantalla no se quiera un salto de linea sino otro comportamiento diferente. Esto se puede lograr a través del uso del parámetro END de la misma función. Este parámetro define el tipo de 'terminación' de la línea impresa por pantalla que por defecto es salto de línea (\n). Veamos un ejemplo para aclarar mas el tema:

for i in range(1,10):
    print(i,end=", ")
print(i+1)

Resultado:

1, 2, 3, 4, 5, 6, 7, 8, 9, 10

Como podemos comprobar Python ya no hace saltos de línea sino que ha sustituido dicho caracter '\n' por ', ' (coma y espacio), haciendo que la salida de la información sea mas legible de forma natural para los lectores occidentales al menos. También es posible eliminar cualquier caracter luego de la salida de cada PRINT(), que podría resultar necesario en ciertos escenarios:

for i in range(1,10):
    print(i,end="")
print(i+1)

Resultado:

12345678910

Podemos comprobar lo dicho anteriormente.

Comentarios

Entradas populares