Python tiene dos construcciones de bucle.
Los bucles while sirven para iteraciones indefinidas (no contadas) y los bucles for para iteraciones definidas (contadas).
Las palabras clave break, continue y else ayudan a personalizar el comportamiento de los bucles.
range() y enumerate() ayudan con el recuento y la indexación de los bucles.
Los bucles while se siguen ejecutando mientras la loop expression o «prueba» se evalúe como True en un boolean context, y terminan cuando se evalúa como False:
# Lists are considered "truthy" in a boolean context if they
# contain one or more values, and "falsy" if they are empty.
>>> placeholders = ["spam", "ham", "eggs", "green_spam", "green_ham", "green_eggs"]
>>> while placeholders:
... print(placeholders.pop(0))
...
'spam'
'ham'
'eggs'
'green_spam'
'green_ham'
'green_eggs'
El for loop básico de Python se describe mejor como un for each que recorre los valores de cualquier objeto iterable y termina cuando la llamada a next() ya no devuelve ningún valor:
>>> word_list = ["bird", "chicken", "barrel", "bongo"]
>>> for word in word_list:
... if word.startswith("b"):
... print(f"{word.title()} starts with a B.")
... else:
... print(f"{word.title()} doesn't start with a B.")
...
'Bird starts with a B.'
'Chicken doesn\'t start with a B.'
'Barrel starts with a B.'
'Bongo starts with a B.'
Cuando no se da un iterable concreto, se usa la secuencia especial range() como contador del bucle.
range() requiere un int ante el cual detener (stop) la secuencia, y puede aceptar opcionalmente los parámetros start y step.
Si no se indica un número start, la secuencia empieza en 0.
Los objetos range() son perezosos (los valores se generan cuando se piden), admiten todas las operaciones comunes de secuencia y ocupan una cantidad fija de memoria, por muy larga que sea la secuencia especificada.
# Here we use range to produce some numbers, rather than creating a list of them in memory.
# The values will start with 1 and stop *before* 7
>>> for number in range(1, 7):
... if number % 2 == 0:
... print(f"{number} is even.")
... else:
... print(f"{number} is odd.")
'1 is odd.'
'2 is even.'
'3 is odd.'
'4 is even.'
'5 is odd.'
'6 is even.'
# range() can also take a *step* parameter.
# Here we use range to produce only the "odd" numbers, starting with 3 and stopping *before* 15.
>>> for number in range(3, 15, 2):
... if number % 2 == 0:
... print(f"{number} is even.")
... else:
... print(f"{number} is odd.")
...
'3 is odd.'
'5 is odd.'
'7 is odd.'
'9 is odd.'
'11 is odd.'
'13 is odd.'
Si se necesitan tanto los valores como sus índices, la función integrada enumerate(<iterable>) devuelve pares (index, value):
>>> word_list = ["bird", "chicken", "barrel", "apple"]
# *index* and *word* are the loop variables.
# Loop variables can be any valid python name.
>>> for index, word in enumerate(word_list):
... if word.startswith("b"):
... print(f"{word.title()} (at index {index}) starts with a B.")
... else:
... print(f"{word.title()} (at index {index}) doesn't start with a B.")
...
'Bird (at index 0) starts with a B.'
'Chicken (at index 1) doesn\'t start with a B.'
'Barrel (at index 2) starts with a B.'
'Apple (at index 3) doesn\'t start with a B.'
# The same method can be used as a "lookup" for pairing items between two lists.
# Of course, if the lengths or indexes don't line up, this doesn't work.
>>> word_list = ["cat", "chicken", "barrel", "apple", "spinach"]
>>> category_list = ["mammal", "bird", "thing", "fruit", "vegetable"]
>>> for index, word in enumerate(word_list):
... print(f"{word.title()} is in category: {category_list[index]}.")
...
'Cat is in category: mammal.'
'Chicken is in category: bird.'
'Barrel is in category: thing.'
'Apple is in category: fruit.'
'Spinach is in category: vegetable.'
La palabra clave continue sirve para saltar a la siguiente iteración:
word_list = ["bird", "chicken", "barrel", "bongo", "sliver", "apple", "bear"]
# This will skip *bird*, at index 0
for index, word in enumerate(word_list):
if index == 0:
continue
if word.startswith("b"):
print(f"{word.title()} (at index {index}) starts with a b.")
'Barrel (at index 2) starts with a b.'
'Bongo (at index 3) starts with a b.'
'Bear (at index 6) starts with a b.'
La palabra clave break (como en muchos lenguajes relacionados con C) sirve para detener la iteración y «salir» del loop más interno que la contiene:
>>> word_list = ["bird", "chicken", "barrel", "bongo", "sliver", "apple"]
>>> for index, word in enumerate(word_list):
... if word.startswith("b"):
... print(f"{word.title()} (at index {index}) starts with a B.")
... elif word == "sliver":
... break
... else:
... print(f"{word.title()} doesn't start with a B.")
... print("loop broken.")
...
'Bird (at index 0) starts with a B.'
'Chicken doesn\'t start with a B.'
'Barrel (at index 2) starts with a B.'
'Bongo (at index 3) starts with a B.'
'loop broken.'
Trabajas como asistente de enseñanza corrigiendo los exámenes de los estudiantes. Llevar la cuenta de los resultados a mano se está volviendo tedioso y propenso a errores. Así que decides hacer las cosas un poco más interesantes creando algunas funciones que cuenten y calculen los resultados de la clase.
Aunque puedes dar «crédito parcial» en las preguntas del examen, las puntuaciones globales del examen tienen que ser ints.
Así que, antes de poder hacer cualquier otra cosa con las puntuaciones de la clase, tienes que repasar las notas y convertir en ints todas las puntuaciones que sean float.
Por suerte para ti, Python tiene la función integrada round() que puedes usar.
Crea la función round_scores(student_scores) que recibe un list de student_scores.
Esta función debe consumir el list de entrada y return un nuevo array con todas las puntuaciones convertidas a ints.
El orden de las puntuaciones en el list resultante no es importante.
>>> student_scores = [90.33, 40.5, 55.44, 70.05, 30.55, 25.45, 80.45, 95.3, 38.7, 40.3]
>>> round_scores(student_scores)
...
[40, 39, 95, 80, 25, 31, 70, 55, 40, 90]
Mientras corregías el examen, te diste cuenta de que algunos estudiantes no rendían tan bien como esperabas. Pero te distrajiste y olvidaste anotar exactamente cuántos estudiantes eran.
Crea la función count_failed_students(student_scores) que recibe un list de student_scores.
Esta función debe contar el número de estudiantes que no tienen una puntuación suficiente y devolver ese recuento como un número entero.
Un estudiante necesita una puntuación mayor que 40 para aprobar el examen.
>>> count_failed_students(student_scores=[90,40,55,70,30,25,80,95,38,40])
5
El profesor al que ayudas quiere encontrar al grupo de estudiantes que ha rendido «mejor» en este examen. Lo que se considera «el mejor» varía, así que tienes que encontrar las puntuaciones de los estudiantes que sean mayores o iguales que el umbral actual.
Crea la función above_threshold(student_scores, threshold) que recibe student_scores (un list de notas) y threshold (el umbral de la «puntuación más alta») como parámetros.
Esta función debe devolver un list con todas las puntuaciones que sean >= que threshold.
>>> above_threshold(student_scores=[90,40,55,70,30,68,70,75,83,96], threshold=75)
[90,75,83,96]
Al profesor al que ayudas le gusta asignar calificaciones con letras además de puntuaciones numéricas. Como los estudiantes rara vez sacan 100 en un examen, los umbrales inferiores de la «calificación con letra» se calculan a partir de la puntuación más alta obtenida y aumentan de forma uniforme entre esa puntuación máxima y el umbral de suspenso de <= 40.
Crea la función letter_grades(highest) que recibe la puntuación «más alta» del examen como argumento y devuelve un list de umbrales inferiores de puntuación para cada intervalo de calificación «al estilo estadounidense»: ["D", "C", "B", "A"].
"""Where the highest score is 100, and failing is <= 40.
"F" <= 40
41 <= "D" <= 55
56 <= "C" <= 70
71 <= "B" <= 85
86 <= "A" <= 100
"""
>>> letter_grades(highest=100)
[41, 56, 71, 86]
"""Where the highest score is 88, and failing is <= 40.
"F" <= 40
41 <= "D" <= 52
53 <= "C" <= 64
65 <= "B" <= 76
77 <= "A" <= 88
"""
>>> letter_grades(highest=88)
[41, 53, 65, 77]
Tienes un array de puntuaciones de examen en orden descendente y otro array de nombres de estudiantes, también ordenados de forma descendente según sus puntuaciones en el examen. Te gustaría emparejar el nombre de cada estudiante con su puntuación y mostrar una clasificación general de la clase.
Crea la función student_ranking(student_scores, student_names) con los parámetros student_scores y student_names.
Empareja cada nombre de estudiante del list student_names con su puntuación del list student_scores.
Puedes asumir que cada list de argumentos estará ordenado de la puntuación más alta a la más baja.
La función debe devolver un list de strings con el formato <rank>. <student name>: <student score>.
>>> student_scores = [100, 99, 90, 84, 66, 53, 47]
>>> student_names = ['Joci', 'Sara','Kora','Jan','John','Bern', 'Fred']
>>> student_ranking(student_scores, student_names)
...
['1. Joci: 100', '2. Sara: 99', '3. Kora: 90', '4. Jan: 84', '5. John: 66', '6. Bern: 53', '7. Fred: 47']
Aunque una puntuación «perfecta» de 100 es poco frecuente en un examen, es interesante saber si al menos un estudiante la ha conseguido.
Crea la función perfect_score(student_info) con el parámetro student_info.
student_info es un list de arrays que contienen el nombre y la puntuación de cada estudiante: [["Charles", 90], ["Tony", 80]].
La función debe return el primer par [<name>, <score>] del estudiante que sacó 100 en el examen.
Si no se encuentra ninguna puntuación de 100 en student_info, debe devolverse un array vacío [].
>>> perfect_score(student_info=[["Charles", 90], ["Tony", 80], ["Alex", 100]])
["Alex", 100]
>>> perfect_score(student_info=[["Charles", 90], ["Tony", 80]])
[]
Regístrate en Exercism para aprender y dominar Python con 17 conceptos146 ejercicios y mentoría humana real, todo gratis.