Python ha due costrutti per i cicli.
I cicli while per un'iterazione indefinita (non contata) e i cicli for per un'iterazione definita (contata).
Le parole chiave break, continue e else aiutano a personalizzare il comportamento di un ciclo.
range() e enumerate() aiutano con il conteggio e l'indicizzazione nei cicli.
I cicli while continuano a essere eseguiti finché l'espressione loop expression o «test» restituisce True in un boolean context, e terminano quando restituisce 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'
Il for loop di base in Python è descritto meglio come un for each che scorre i valori di un qualsiasi oggetto iterabile, e termina quando non ci sono più valori restituiti dalla chiamata a next():
>>> 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.'
Quando non viene fornito un iterable specifico, la sequenza speciale range() viene usata come contatore di un ciclo.
range() richiede un int davanti al quale fermare (stop) la sequenza, e può accettare facoltativamente i parametri start e step.
Se non viene fornito nessun numero start, la sequenza inizia da 0.
Gli oggetti range() sono pigri (i valori vengono generati su richiesta), supportano tutte le operazioni comuni sulle sequenze e occupano una quantità fissa di memoria, indipendentemente da quanto sia lunga la sequenza specificata.
# 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.'
Se servono sia i valori sia i loro indici, la funzione integrata enumerate(<iterable>) restituisce coppie (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 parola chiave continue permette di saltare avanti al ciclo di iterazione successivo:
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 parola chiave break (come in molti linguaggi della famiglia C) permette di interrompere l'iterazione e «uscire» dal loop più interno che 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.'
Sei un assistente didattico che corregge gli esami degli studenti. Tenere traccia dei risultati a mano sta diventando noioso e fonte di errori. Decidi di rendere le cose un po' più interessanti mettendo insieme alcune funzioni per contare e calcolare i risultati della classe.
Anche se puoi dare un «credito parziale» sulle domande dell'esame, i punteggi complessivi dell'esame devono essere degli int.
Quindi, prima di poter fare qualsiasi altra cosa con i punteggi della classe, devi passare in rassegna i voti e trasformare in int tutti i punteggi che sono dei float. Per tua fortuna, Python ha la funzione integrata round() che puoi usare.
Crea la funzione round_scores(student_scores) che prende una list di student_scores.
Questa funzione deve consumare la list di input e return una nuova lista con tutti i punteggi convertiti in int.
L'ordine dei punteggi nella list risultante non è 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]
Mentre correggevi l'esame, hai notato che alcuni studenti non se la cavavano bene come speravi. Ma eri distratto e hai dimenticato di annotare esattamente quanti studenti.
Crea la funzione count_failed_students(student_scores) che prende una list di student_scores.
Questa funzione deve contare il numero di studenti che non hanno un punteggio sufficiente e restituire quel numero come intero.
Uno studente deve avere un punteggio maggiore di 40 per ottenere la sufficienza all'esame.
>>> count_failed_students(student_scores=[90,40,55,70,30,25,80,95,38,40])
5
L'insegnante che assisti vuole trovare il gruppo di studenti che ha ottenuto «il migliore» risultato in questo esame. Ciò che conta come «il migliore» cambia nel tempo, quindi devi trovare i punteggi degli studenti che sono maggiori o uguali alla soglia attuale.
Crea la funzione above_threshold(student_scores, threshold) che prende student_scores (una list di voti) e threshold (la soglia del «punteggio più alto») come parametri.
Questa funzione deve restituire una list con tutti i punteggi che sono >= a threshold.
>>> above_threshold(student_scores=[90,40,55,70,30,68,70,75,83,96], threshold=75)
[90,75,83,96]
L'insegnante che assisti ama assegnare sia voti in lettere sia punteggi numerici. Dato che gli studenti raramente prendono 100 a un esame, le soglie inferiori dei «voti in lettere» si calcolano in base al punteggio più alto ottenuto e aumentano in modo uniforme tra il punteggio più alto e la soglia di insufficienza di <= 40.
Crea la funzione letter_grades(highest) che prende come argomento il punteggio «più alto» dell'esame e restituisce una list di soglie inferiori per ogni intervallo di voto «all'americana»: ["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]
Hai un array di punteggi d'esame in ordine decrescente e un altro array di nomi di studenti, ordinato anch'esso in ordine decrescente in base ai loro punteggi d'esame. Vuoi abbinare ogni nome di studente al suo punteggio d'esame e stampare una classifica complessiva della classe.
Crea la funzione student_ranking(student_scores, student_names) con i parametri student_scores e student_names.
Abbina ogni nome di studente nella list student_names al suo punteggio nella list student_scores.
Puoi presumere che ogni list passata come argomento sia ordinata dal punteggio più alto a quello più basso.
La funzione deve restituire una list di stringhe con il 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']
Anche se un punteggio «perfetto» di 100 è raro a un esame, è interessante sapere se almeno uno studente lo ha ottenuto.
Crea la funzione perfect_score(student_info) con il parametro student_info.
student_info è una list di liste che contengono il nome e il punteggio di ogni studente: [["Charles", 90], ["Tony", 80]].
La funzione deve fare return della prima coppia [<name>, <score>] dello studente che ha preso 100 all'esame.
Se in student_info non c'è nessun punteggio di 100, va restituita una lista vuota [].
>>> perfect_score(student_info=[["Charles", 90], ["Tony", 80], ["Alex", 100]])
["Alex", 100]
>>> perfect_score(student_info=[["Charles", 90], ["Tony", 80]])
[]
Iscriviti a Exercism per imparare e padroneggiare Python con 17 concetti146 esercizi e il mentoring di persone reali, tutto gratis.