En esta presentación nos dedicaremos a afianzar el concepto de "patrón de recorrido". En este sentido no veremos conceptos nuevos algorítmicos, sino que vamos a dedicar un momento a repasar patrones de recorrido de listas y, en general, de cualquier secuencia de valores. Empecemos con el patrón de recorrido total. Lo utilizamos cuando necesitamos recorrer toda la estructura secuencial, es decir, una lista o una cadena caracteres. Por ejemplo, cuando deseamos calcular la suma de todos los valores numéricos almacenados en una lista, o cuando queremos obtener el elemento de menor valor de una lista, etcétera. Para eso contamos con tres opciones. Podemos utilizar una instrucción "while", podemos hacerlo con un "for-in range" o podemos hacerlo con un "for-in". Para ver las diferencias entre estas tres implementaciones, utilizaremos un ejemplo muy sencillo que consiste en una función que nos calcula la suma de todos los valores numéricos contenidos en una lista. Empecemos, entonces, con la instrucción "while". Cuando utilizamos un ciclo implementado con "while", es muy importante tener presente que necesitaremos un índice para movernos en la lista y que este empieza siempre en cero, puesto que queremos recorrer todos los elementos de la lista desde la primera posición. La condición de iteración es muy simple, vamos a iterar, es decir, a repetir el bloque de instrucciones mientras "i" sea inferior a la longitud de la lista. Con esta condición garantizamos que vamos a recorrer todos los elementos de la lista hasta llegar a la última posición. Es muy importante recordar que debemos incrementar el índice en uno. De esta manera, iteración tras iteración, nuestra variable va incrementándose hasta que llega un momento en que se iguala a la longitud de la lista, y esto es lo que nos va a permitir interrumpir el ciclo. Recordemos que la variable "i" sirve para recorrer los índices de la lista, esto es, las posiciones de los elementos. Por esta razón, para obtener los valores de los elementos, debemos utilizar el operador de indexación, es decir, los corchetes cuadrados. Pasemos ahora a ver la implementación de la misma función, pero con una instrucción "for-in range". Importante: necesitamos igualmente un índice para movernos en la lista, el cual irá desde la posición cero hasta la longitud de la lista menos uno. Aquí la variable "i" nos sirve igualmente para recorrer los índices de la lista, es decir, las posiciones de sus elementos. Por esa razón debemos extraer el elemento de interés con el operador de indexación, que son los corchetes cuadrados. Pasemos ahora a ver la implementación de la misma función con la instrucción "for-in". Aquí la variable que declaremos dentro del "for", nos servirá para recorrer cada elemento de la lista. Es por esta razón que podemos utilizarla directamente y no necesitamos extraer el elemento con el operador de indexación, puesto que en cada número ya tenemos cada uno de los elementos de la lista. Veamos los resultados de las diferentes ejecuciones. Con nuestra lista "mi_lista", que tiene como valores: 32, 12, 87, 47, 0, 33 y 10; podemos constatar que las diferentes implementaciones de nuestra función que suma los valores numéricos de la lista, obtenemos el mismo resultado. Pasemos ahora a estudiar el patrón de recorrido parcial. Lo utilizamos cuando no necesitamos recorrer toda la lista o secuencia de valores. Y esto es porque existe una condición que debemos verificar en cada iteración para saber si detenemos el ciclo o continuamos iterando. Por ejemplo, decidir si al menos un valor es positivo en una lista de números. Empezamos a recorrer la lista desde la primera posición, tan pronto como encontremos un valor positivo, podemos detener la ejecución del ciclo. Un recorrido parcial solo se puede implementar con la instrucción "while". Nunca lo podemos hacer con un "for-in" porque es necesario interrumpir el ciclo cuando se encuentra lo que se está buscando. Pero tenemos dos opciones, podemos implementar el "while" con centinela o sin centinela. Para ver la diferencia entre estas dos opciones de implementación, utilizaremos una función muy sencilla que nos retorna la posición de un elemento dentro de una lista. Si el elemento no se encuentra en la lista, esta función retorna el valor menos uno. Necesitamos entonces: una variable que llamamos "índice", para movernos en la lista, la cual empieza con el valor cero; necesitamos también un centinela para parar el ciclo cuando hayamos encontrado la posición del elemento. En este ejemplo en particular, estamos utilizando un centinela de tipo booleano que inicializamos con el valor "False", pero recordemos que el centinela puede ser, en realidad, de cualquier tipo. La condición de iteración, es decir, la condición para continuar el ciclo, será doble. Por un lado, que nuestro índice sea menor que la longitud de la lista y que nuestro centinela tenga el valor "False", que fue el valor que le dimos al inicio. Si encontramos el elemento buscado, debemos cambiar el valor del centinela a "True" para interrumpir el ciclo en la siguiente iteración, y además, guardar en nuestra variable "posición", justamente la posición donde encontramos el valor buscado. Por último, dado que estamos dentro de un "while", recordemos siempre incrementar el índice para continuar el recorrido. Al final, se retorna a la posición del elemento buscado o menos uno, si no lo encontró, dado que nunca se cumplió la condición del "if" y nuestra variable "posición" mantendrá su valor inicial. Recordemos que es muy importante controlar siempre que el índice que utilizamos para recorrer la lista esté dentro del tamaño de la lista, esto es entre cero y la longitud menos uno, para evitar que nuestro programa se vaya a morir por un error de "index out of range". Veamos ahora la misma implementación pero sin utilizar el centinela. De cualquier manera, necesitamos el índice para movernos en la lista, el cual empieza siempre en cero. Es nuestra condición de iteración la que va a cambiar, puesto que ya no tenemos el centinela y debemos plantear directamente en el "while" la condición de continuación. Veamos acá. Mantenemos la condición de que nuestro índice sea menor que la longitud de la lista para evitar salirnos de la estructura y que no hayamos encontrado lo que estamos buscando. En este ejemplo en particular, que el elemento que está en la posición "i" sea diferente del elemento que entra como parámetro, que es el que estamos buscando. Mientras esta condición compuesta se cumpla, nosotros simplemente debemos incrementar el índice para continuar recorriendo la lista. Al finalizar el ciclo debemos investigar qué fue lo que ocurrió, cuál de esas dos condiciones fue la que no se cumplió. Si nuestro índice tiene el mismo valor de la longitud de la lista, quiere decir que no encontró el elemento, en cuyo caso en nuestra variable "posición" guardamos el valor menos uno. De lo contrario, quiere decir que el ciclo se interrumpió porque encontramos justamente el elemento que estábamos buscando, en cuyo caso, en nuestra variable "posición", guardamos el índice donde se encontró dicho elemento. Al final, se retorna a la posición del elemento buscado o menos uno, si el algoritmo no lo encontró. Muy importante: que utilicemos o no centinela, siempre recordemos que debemos controlar que nuestro índice no se salga de la longitud de la lista para evitar que el programa se muera. Ahora veamos los resultados de las diferentes ejecuciones con nuestra lista, "mi_lista", que tiene los siguientes valores: 32, 12, 87, 47, 0, 33 y 10. Si deseamos buscar el valor 87 con centinela, obtenemos que se encuentra en la posición dos de la lista. El valor 100 no se encuentra. Sin centinela obtenemos el mismo resultado, el 87 se encuentra en la posición dos y el 100 no se encuentra.