Python

Tuples              

Del tutto simili alle liste sono le tuples, che si presentano anch'esse come sequenze finite (ma senza limiti prefissati) di elementi. le differenze rispetto alle liste sono fondamentalmente due:

  1. le liste sono delimitate da una coppia di parentesi quadre, le tuples da una coppia di parentesi tonde.
  2. le tuple sono immutabili.

In base al punto due, esse vengono utilizzate quando siamo assolutamente certi che il numero di elementi sarà quello che abbiamo definito. Vale subito la pena di capire quando usare le liste e quando usare le tuple. Un primo punto, pare, sia relativo alle performance che dovrebbero avvantaggiare le tuple ma non ho riscontri univoci in tal senso, anche se, effettivamente, le cose sembrano stare così. Si può pensare a qualche ottimizzazione da parte dell'interprete una volta note le dimensioni che deve trattare. La differenza principale tuttavia proprio nel discorso della immutabilità che garantisce sicurezza ai dati interni (con qualche eccezione, in realtà, da un certo punto di vista). Per contro non si possono, per quanto detto, nè inserire nè togliere dati, il che causa una certa rigidità. Alle tuple è riconosciuto, in funzione della loro rigidità, un valore "espressivo" maggiore, secondo alcuni autori (opinabile, a mio avviso). Una tuple, può essere usata come chiave in un dictionary, che vedremo cos'è, una lista no. Queste sono le premesse, passiamo a vedere cosa abbiamo per le mani.

t01 = () è una tuple vuota
t02 = (1,2,3) è una tuple con tre elementi.

molto semplice. E' ovviamente permesso che gli elementi all'interno siano di origine diversa:

>>> t = (1, 'a', 3*3)
>>> t
(1, 'a', 9)

In fase di inizializzazione è anche possibile non usare le tonde laddove laddove non vi siano ambiguità.

>>> t04 = 1,2,3,4
>>> t04
(1, 2, 3, 4)

Un altro modo è per concatenazione:

>>> tt = (2,3,4) + (5,6,7)
>>> tt
(2, 3, 4, 5, 6, 7)
>>> ttt = (10,) + tt[2:]
>>> ttt
(10, 4, 5, 6, 7)

nel primo caso abbiamo unito due tuple, unendole col segno +, nel secondo caso, per creare la tuple di nome ttt abbiamo preso un singolo elemento, definendo dapprima una tuple costituita da un solo elemento (si noti la definizione, un numero seguito da una virgola) e quindi una tuple presa in considerazione a partire dall'indice 2 in avanti.

Partiamo a vedere come si può lavorare con le nostre tuple, ricordando che non si possono aggiungere nè cancellare elementi.
Come le liste anche le tuple sono indicizzate. Gli indici partono da 0 fino ad arrivare ad n-1 dove n è il numero di elementi. Per accedere ad un singolo elemento basta usare il solito operatore [].

>>> t04[1]
2

è possibile anche usare indici negativi

>>> t04[-1]
4

vale insomma quanto già incontrato con le liste, potete applicare quanto vista per esse da un punto di vista rappresentativo.

come abbiamo visto è possibile selezionare una parte della tuple:

>>> tt
(2, 3, 4, 5, 6, 7)
>>> tt[3:]
(5, 6, 7)

con gli indici che vanno, come al solito da 0 ad n-1 con n che è il numero di elementi della tuple.

Per sapere a priori quanti sono gli elementi di una tuple invece si usa len(tuple) quindi:

>>> len(t04)
4

Metodi interessanti sono:
index - che ci restituisce il primo indice dell'elemento indicato
count - che ci dice quante volte appare l'elemento indicato nella tuple.

>>> tup = (1,2,3,3,4,5)
>>> tup.index(3)
2
>>> tup.count(3)
2

da notare che se come argomento di index indicate un elemento che non esiste ne risulta fuori un errore che deve essere gestito.
Non sono invece presenti tutti gli operatori di modifica previsti per le liste e nemmeno copy. Per copiare un lista partendo da un'altra si può ricorrere all'operatore =.

>>> a = (1,2,3)
>>> b = a
>>> b
(1, 2, 3)

Il discorso relativo alle tuples, come si vede è molto semplice e del tutto simile a quanto visto per le liste. Una piccola complicazione dal punto di vista dell'assoluta immutabilità dei dati è la seguente:

>>> t = ('a', 'b', [1,2,3])
>>> t
('a', 'b', [1, 2, 3])
>>> t[2][1] = 8
>>> t
('a', 'b', [1, 8, 3])

All'interno dalla tuple t è stata inserita una lista,che, come abbiamo visto nel capitolo precedente, è modificabile. La riga evidenziata in rosso effettua una variazione su di un elemento della lista interna alla tuple e tale modifica viene accetatta. Questo è ovviamente logico e ci permette di capire che la sicurezza che la tuple assicura ai sui elementi è applicata sul loro numero e sulla loro esistenza ma se si tratta di elementi modificabili essi possono essere comunque modificati. Ripeto, è logico, ma è bene saperlo per non prendere come un dogma assoluto la questione dell'immutabilità interna alle tuple.

Un tipico esempio che rende utili le tuple è quello classico dello scambio di valori tra due variabili, lo troverete un po' ovunque si parli di tuple in Python. Vediamo l'esempio:

>>> x = 4
>>> y = 5
>>> temp = x
>>> x = y
>>> y = temp
>>> x
5
>>> y
4
>>>

Questo è il procedimento classico per scambiare i valori tra x e y. Funziona anche in Python ovviamente. Ma c'è una via più breve:

>>> xx = 3
>>> yy = 4
>>> xx,yy = yy,xx
>>> xx
4
>>> yy
3
>>>

Per come sono definite le tuple, la parte destra della riga in rosso sono in pratica un tuple di variabili mentre la parte destra è una tuple di valori. Di qui l'immediatezza dell'assegnazione. Molto comodo.

Come vedremo le tuple possono essere anche essere utilizzate come valori di ritorno di funzioni, ne parleremo appunto nel capitolo a queste dedicato.