Argomenti Mutabili nelle Funzioni

Python ha una varietà di tipi di dati, alcuni dei quali possono essere modificati dopo la loro creazione e altri no. Quando parliamo di tipi che possono essere modificati, ci riferiamo a essi come tipi "mutabili". Al contrario, quelli che non possono essere cambiati sono chiamati tipi "immutabili".

Tipi Mutabili

I tipi mutabili più comuni sono list, dict e set. Ecco un esempio di una lista:
fruits = ['apple', 'banana', 'cherry']
print(fruits, type(fruits))  # ['apple', 'banana', 'cherry'] <class 'list'>
Con una list, puoi cambiare i suoi elementi, aggiungerne di nuovi o rimuovere quelli esistenti:
fruits[1] = 'blueberry'       # Cambia 'banana' in 'blueberry'
fruits.append('dragonfruit')  # Aggiunge 'dragonfruit' alla fine della lista
print(fruits)                 # ['apple', 'blueberry', 'cherry', 'dragonfruit']

Tipi Immutabili

D'altra parte, esempi di tipi immutabili sono int, float, string e tuple. Una volta creati, non puoi cambiare il loro contenuto. Ecco un esempio con una string:
message = 'hello'
print(message, type(message))  # hello <class 'str'>
Se provi a cambiare parte della string, Python non lo permetterà:
message[0] = 'H'  # Tentare di cambiare 'h' in 'H' genererà un TypeError
Come mai int è immutabile? Non possiamo cambiare il valore con += o -=?
Quando parliamo di mutabilità in Python, intendiamo che il valore effettivo memorizzato in memoria possa essere alterato. Ad esempio, quando abbiamo una lista, possiamo cambiare un elemento nella lista, ed è ancora la stessa lista in memoria.
Gli interi in Python sono immutabili. Ciò significa che il valore in memoria non può essere modificato. Se abbiamo un intero, a = 5, e svolgiamo un'operazione come a += 2, potrebbe sembrare che abbiamo cambiato a. Tuttavia, ciò che Python ha effettivamente fatto è creare un nuovo oggetto in memoria con valore 7 e aggiornare a per puntare a questo nuovo oggetto. L'originale 5 non è stato cambiato in memoria, ed è per questo che gli int sono considerati immutabili.
a = 5
print(id(a))  # Questo stampa la posizione di memoria di a. Supponiamo che sia 1001

a += 2
print(a)      # Questo stampa 7
print(id(a))  # Questo stamperà una diversa posizione di memoria, supponiamo 1002
La funzione id in Python restituisce l'identità di un oggetto, che è unica e costante per tutta la durata dell'oggetto. Quindi, quando vediamo che l'identità di a è cambiata dopo l'operazione a += 2, è un chiaro segno che a ora punta a un nuovo oggetto in memoria. L'intero originale 5 non è stato modificato, confermando che gli interi sono effettivamente immutabili in Python.

Argomenti Mutabili nelle Funzioni

Quando passiamo un oggetto mutabile (come una lista) a una funzione, Python fornisce alla funzione un riferimento a quell'oggetto. Ciò significa che se la funzione modifica l'oggetto mutabile, tale modifica sarà visibile anche al di fuori della funzione.
Usiamo una funzione che riceve una lista e vi aggiunge un elemento:
def add_item(my_list):
    my_list.append('added item')  # Aggiunge un nuovo elemento alla lista

shopping_list = ['apples', 'bananas', 'cherries']
print(shopping_list)  # Stampa: ['apples', 'bananas', 'cherries']

# Ora usiamo la funzione per aggiungere un elemento alla nostra lista della spesa
add_item(shopping_list)
print(shopping_list)  # Stampa: ['apples', 'bananas', 'cherries', 'added item']
Come puoi vedere, quando abbiamo stampato shopping_list dopo aver chiamato la funzione add_item, la lista aveva un nuovo elemento. Questo è successo anche se non abbiamo modificato direttamente shopping_list al di fuori della funzione.
Tuttavia, è fondamentale capire che se assegni un nuovo valore all'intero oggetto mutabile all'interno della funzione, ciò non influirà sull'oggetto originale. Questo perché stai dando alla variabile locale della funzione un nuovo riferimento, non stai modificando l'oggetto originale. Vediamo un esempio:
def change_list(my_list):
    my_list = ['entirely', 'new', 'list']  # Questo non influirà sulla lista originale

shopping_list = ['apples', 'bananas', 'cherries']
change_list(shopping_list)
print(shopping_list)  # Continua a stampare: ['apples', 'bananas', 'cherries']
Anche se abbiamo chiamato la funzione change_list con shopping_list come argomento, il contenuto di shopping_list non è cambiato. Questo perché all'interno della funzione, my_list ha ricevuto un nuovo riferimento (a una lista completamente nuova), mentre il riferimento a shopping_list è rimasto invariato.
Il punto fondamentale è: quando passi un oggetto mutabile a una funzione in Python, ricorda che se la funzione modifica l'oggetto (come aggiungere un elemento a una lista), la modifica è permanente e visibile al di fuori della funzione. Ma se assegni un nuovo valore all'intero oggetto all'interno della funzione, ciò non influirà sull'oggetto originale.
 
To check your solution you need to sign in
Sign in to continue