Created: 2024-02-16 ven 19:46
Durante le ultime lezioni girando per i banchi mi sono annotato gli errori piu' frequenti che vengono commessi durante la risoluzione degli esercizi;
Oggi vediamo qualche esercizio ispirato a questi errori, per capire un po' meglio come funzionano alcune cose "cattivelle";
l = (1,2,3,4,5)
l[1] = 14
print(l)
Cosa succede se eseguiamo questo codice?
Errore!
Le tuple sono simili alle liste, ma non potete modificarle una volta create.
l1 = [1,2,3,4,5]
l2 = l1
l1[0] = "X"
print(l1)
print(l2)
Cosa viene stampato?
['X', 2, 3, 4, 5]
['X', 2, 3, 4, 5]
??
Usando \(l2 = l1\) abbiamo creato un altro puntatore allo stesso oggetto in memoria.
Quindi accedere alla lista \([1,2,3,4,5]\) tramite \(l1\) o tramite \(l2\) e' la stessa cosa.
Per creare una copia della lista l1, e' necessario usare la direttiva .copy()
Vediamo un altro esercizio:
t1 = [[1,2,3], [1,2,3]]
t2 = t1.copy()
t2[0][1] = 23
print(t1)
print(t2)
Cosa viene stampato?
[[1, 23, 3], [1, 2, 3]]
[[1, 23, 3], [1, 2, 3]]
Il metodo copy() non funziona nel modo che tutti pensiamo…
copy() crea una nuova lista contenente i riferimenti agli oggetti della lista di partenza;
Morale della favola: quando avete lavorate con oggetti complessi (dizionari o liste innestate) usate il metodo deepcopy():
from copy import deepcopy
t1 = [[1,2,3], [1,2,3]]
t2 = deepcopy(t1)
t2[0][1] = 23
print(t1)
print(t2)
[[1, 2, 3], [1, 2, 3]]
[[1, 23, 3], [1, 2, 3]]
I cili while sono simili ai cicli for, con qualche piccola differenza;
x = 0
while x < 10:
print(x)
Cosa viene stampato?
0
0
0
...
A differenza dei cicli for, nei cicli while la variabile di controllo non viene incrementata automaticamente.
La versione corretta del codice per stampare i numeri da 0 a 9 e' la seguente:
x = 0
while x < 10:
print(x)
x+=1
I cili while possono tornare utili:
Quando ci serve flessibilita' nell'aggiornamento della variabile di controllo;
Quando conosciamo la condizione di terminazione di un ciclo ma non sappiamo esattamente come iterare;
Per capire meglio l'utilita' dei while, vediamo un esercizio:
Dato un valore \(n\) che sia una potenza del 2, stampare la seguente successione di valori: \([\frac{n}{2}, \frac{n}{4}, \frac{n}{8}, ..., 1]\)
Soluzione:
n = 64
while n > 1:
n = n/2
print(n)
La prima parte e' semplice (esercizio medium regalato da verifica), non serve usare i cicli while;
Nella seconda parte invece e' quasi obbligatorio;
Per effettuare una divisione intera (scartando il resto), si usa l'operatore //;
with open("test.txt") as f:
values = f.read().splitlines()
fuel = 0
for value in values:
fuel += int(value) // 3 - 2
print(fuel)
with open("test.txt") as f:
values = [int(x) for x in f.read().splitlines()]
fuel = 0
for value in values:
while value // 3 - 2 > 0:
value = value // 3 - 2
fuel += value
print(fuel)