Come anticipato, le tuple si differenziano dalle liste soprattutto per via del fatto di essere immutabili, una volta che viene assegnato un elemento ad una tupla quest’ultimo non potrà essere modificato. E’ comunque possibile alterare alcune componenti di una tupla, se per esempio un elemento di una tupla è rappresentato da un tipo di dato modificabile, come nel caso di una lista, i suoi elementi annidati potranno subire delle variazioni. Nello stesso modo si potranno effettuare delle riassegnazioni di valore a carico di una tupla.
Immutabilità degli elementi di una tupla
Nel caso in cui si tenti di modificare un elemento di una tupla, l’esecutore di Python impedirà il completamento di tale operazione gestendo l’eccezione e inviando un’apposita segnalazione all’utilizzatore. A questo propostio si definisca una tupla composta da elementi di natura differente:
# Definizione di una tupla
>>> nome_tuple = (6, 4, 5, [8, 7])
Si avrà in questo modo una tupla composta da 4 elementi, 3 numeri interi e una lista a sua volta composta da 2 interi. Il secondo elemento della tupla, con indice uguale a "1" ha un valore pari a "4", si tenti ora di modificare questo valore da "4" a "3":
# Tentativo di modifica del valore di una tupla
>>> nome_tuple[1] = 3
Una volta lanciata l’istruzione Python notificherà la presenza di un errore attraverso il seguente output:
>>>nome_tuple[1] = 3
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
nome_tuple[1] = 3
TypeError: 'tuple' object does not support item assignment
L’ultima riga dell’output prodotto presenta un messaggio abbastanza chiaro: le tuple non supportano la riassegnazione degli elementi, viene così; confermata l’ummutabilità degli elementi di una tupla.
Tuple ed elementi annidati mutabili
la tupla presentata nell’esempio precedente contiene un elemento mutabile, si tratta nello specifico di una lista che all’interno della tupla ha come indice "3" e come valori "8" e "7" che a loro volta hanno come indici "0" e "1". Le tuple consentono di modificare gli elementi annidati di un elemento mutabile, questo significa che se una tupla presenta al suo interno una lista, gli elementi di quest’ultima potranno subire dei riassegnamenti.
Si provi quindi a modificare il valore dell’elemento della lista che ha come indice "0" da "8" a "2":
# Riassegnazione di un elemento di una lista in una tupla
>>> nome_tuple[3][0] = 2
Questa volta non vi sarà alcuna notifica di errore, l’avvenuta riassegnazione potrà infatti essere confermata dalla chiamata dell’elemento riassegnato tramite il suo numero d’indice:
# Verifica del valore dell'elemento di una lista
>>> nome_tuple[3][0]
2
Riassegnazione di una tupla
Il nome utilizzato per definire una tupla agisce come una sorta di puntatore verso degli elementi immutabili, questo però non significa che essa non possa essere riposizionata per puntare su un nuovo gruppo di valori. Sarà infatti possibile riassegnare una tupla nel suo compesso associando ad essa valori differenti da quelli iniziali. Nell’esempio seguente la tupla precedentemente definita viene riassegnata utilizzando nuovi elementi:
# Riassegnazione di una tupla
>>> nome_tuple = ('p','y','t','h','o','n')
>>> nome_tuple
('p', 'y', 't', 'h', 'o', 'n')
In questo caso l’istruzione lanciata non darà luogo ad errori, in quanto non si è tentato di assegnare nuovi valori agli elementi che compongono la tupla, per definizione immutabili, ma la tupla stessa che è stata inizializzata nuovamente.
Concatenazione delle tuple
Più tuple possono essere concatenate utilizzando l’operatore "+" che agisce come operatore di concatenazione:# Concatenazione di due tuple
>>> a_tuple = (1,2,3)
>>> b_tuple = (4,5,6)
>>> c_tuple = a_tuple + b_tuple
>>> c_tuple
(1, 2, 3, 4, 5, 6)
Il numero di tuple concatenabili è virtualmente illimitato, sarà inoltre possibile concatenare tuple i cui elementi appartengono a tipi di dato differenti:
# Concatenare tuple con tipi di dati differenti
>>> d_tuple = ('a','b','c',[7,8])
>>> e_tuple = c_tuple + d_tuple
>>> e_tuple
(1, 2, 3, 4, 5, 6, 'a', 'b', 'c', [7, 8])
>>>
L’interprete di Python si occuperà di distribuire gli indici interni alla tupla risultante sulla base dell’ordine con il quale le tuple sono state concatenate. Nel caso dell’ultima concatenazione effettuata abbiamo una tupla composta da 10 elementi con numero indice da "0" a "9", dato che l’ultimo elemento è una lista composta da due elementi con indice da "0" a "1" avremo per esempio:
>>> e_tuple[9][0]
7
Un caso particolare è quello della concatenazione di valori ripetuti che si basa sull’utilizzo dell’operatore "*":
# Concatenzaione di valori ripetuti
>>> f_tuple = ('x','y','7') * 3
>>> f_tuple
('x', 'y', '7', 'x', 'y', '7', 'x', 'y', '7')
In questo modo sarà possibile specificare il numero di volte che uno o più elementi dovranno essere ripetutti all’inteno di una tupla tramite una semplice moltiplicazione.
Tuple e rimozioni
Gli elementi che compongono una tupla sono immutabili e non possono essere cancellati, nel caso in cui si tenti di cancellare un elemento di una tupla attraverso la chiamata del suo numero indice si riceverà in output una notifica di errore; è invece possibile utilizzare la keyword del per cancellare una tupla nel suo insieme:
# Tentativo di cancellazione di un elemento di una tupla
>>> del f_tuple[5]
Traceback (most recent call last):
File "<pyshell#22>", line 1, in <module>
del f_tuple[5]
TypeError: 'tuple' object doesn't support item deletion
# Cancellazione di una tupla
>>> del f_tuple
>>> f_tuple
Traceback (most recent call last):
File "<pyshell#24>", line 1, in <module>
f_tuple
NameError: name 'f_tuple' is not defined
Se provassimo a cancellare un elemento di una tupla Python ci informerebbe che tale funzionalità non è supportata, la rimozione dell’intera tuple avverrà invece regolarmente e non sarà quindi più possibile richiamare i valori di quest’ultima perché non più definita.