< Home
Stampa

Tuple, Set , Stringhe, Dizionari

Sommario

Tuple

Le tuple sono collezioni ordinate ma non modificabili di elementi. Si usa l’operatore ()

tuple1 = (1,2,3)

Una tupla di un solo elemento richiede comunque la virgola:

tuple2 = (6,)

Come detto non sono modificabili, quindi una volta creata non si possono aggiungere, rimuovere o cambiare elementi.

Le tuple sono usate per proteggere i dati da modifiche accidentali, per gestire di normale gruppi di dati eterogenei, e per raggruppare più valori insieme come risultato di una operazione.

Le tuple hanno le stesse funzioni disponibili per le liste, eccetto quelle che le modificano.

coordinates = (45.09, 9.18)
print(coordinates[0]) # 45.09

E’ possibile scorporare (operazione chiamata unpacking) memorizzando i loro valori in altrettante variabili quanti sono i loro elementi.

lat, lon = coordinates

L’unpacking non necessita nemmeno di una tupla definita:

lat, lon = (45.09, 9.18)
lat, lon = 45.09, 9.18 # le parentesi non sono obbligatorie

E’ utile anche per invertire il valore di variabili:

a, b = b, a

Con le tuple ora possiamo modificare l’esempio della lezione precedente inserendo anche il motivo di spesa della lista spese:

spese = []  # lista di coppie (importo, motivo)
fine = False

while not fine:
    print('''\nMenu
  1: inserisci spesa
  2: elimina spesa
  3: mostra totale spese
  0: esci''')
    scelta = int(input("Inserisci scelta: "))

    if scelta == 0:
        fine = True

    elif scelta == 1:
        importo = float(input("Inserisci importo: "))
        motivo = input("Inserisci motivo: ")
        spese.append((importo, motivo))

    elif scelta == 2:
        indice = int(input("Inserisci indice da eliminare: "))
        del spese[indice]

    elif scelta == 3:
        print("\n\nINDICE\tIMPORTO\tMOTIVO")
        for indice, (importo, motivo) in enumerate(spese):
            print(f"{indice}\t{importo:.2f}\t{motivo}")
        totale = sum(importo for importo, _ in spese)
        print(f"\nTotale: {totale:.2f}")

Zip

La funzione zip permette di accoppiare elementi due liste in una lista unica che ha come elementi coppie di valori delle due liste originali.

nomi = ["Mario", "Luisa"]
voti  = [6, 8]

zipped_list = zip(nomi, voti) # [("Mario", 6), ("Luisa", 8)]

for nome, voto in zipped_list:  #unpacking
    print(f"{nome} ha preso {voto}")

Se si accoppiano liste di lunghezza diversa, si perdono gli elementi eccedenti la lista più lunga.

E’ possibile eseguire anche l’unzip:

coppie = [("Maria", "Roma"), ("Giovanni", "Milano")]

nomi, citta = zip(*coppie)

print(nomi)  # ('Maria', 'Giovanni')
print(citta) # ('Roma', 'Milano')

Esempio:

num_materie = int(input("Inserisci il numero materie"))

materie = []
voti = []
              
for i in range(num_materie):
  materia = input(f"Inserisci materia {i+1}:")
  materie.append(materia)
  voto = float(input("Inserisci voto: "))
  voti.append(voto)

print("MATERIA\tVOTO")
for materia, voto in zip(materie, voti):
  print(f"{materia}\t{voto}")

Set

Un set è una collezione non ordinata di elementi unici. Per unici si intende che non sono permessi valori duplicati nello stesso set. Si creano o con le parentesi graffe {} o con l’istruzione set() a partire da altra collezione.

frutta = {"mela", "banana", "arancia"}

# Creazione da una lista (rimuove i duplicati automaticamente)
lista_con_duplicati = [1, 2, 2, 3, 4, 4]
mio_set = set(lista_con_duplicati)

print(mio_set)  # {1, 2, 3, 4}

Gli elementi di un set non sono accessibili tramite indici, in quanto non sono ordinati. E’ quindi possibile fare:

colori = {"rosso", "verde", "blu"}

for c in colori:
    print(c)

Ma non è garantito l’ordine. Per ordinare si può comunque generare una lista anche temporanea ordinata con sorted:

numeri = {4, 1, 9, 2}

for n in sorted(numeri):  # Ordina prima di ciclare
    print(n)

I set prevedono le operazioni insiemistiche: intersezione &, unione |, differenza – (elementi nel primo insieme ma non nel secondo), e xor ^ (il contrario dell’intersezione):

set_a = {1, 2, 3, 4}
set_b = {3, 4, 5, 6}

# Intersezione (elementi in A E B)
print(set_a & set_b)  # {3, 4}

# Unione (tutti gli elementi)
print(set_a | set_b)  # {1, 2, 3, 4, 5, 6}

# Differenza (elementi in A ma NON in B)
print(set_a - set_b)  # {1, 2}

# Differenza simmetrica (elementi in A o B ma non entrambi)
print(set_a ^ set_b)  # {1, 2, 5, 6}

Sono infine previsti i frozenset, che sono immutabili, ovvero non è possibile aggiungere o eliminare valori.

mio_frozen = frozenset([1, 2, 3])

Gli insiemi sono utili in tutti quegli scenari in cui vogliamo rappresentare gruppi di informazioni univoche e non duplicabili, ad esempio gli ingredienti di una ricetta o una rosa di giocatori di una squadra. Possono servire inoltre per eliminare i duplicati da una lista (la si trasforma prima in set e poi di nuovo in lista), per unire senza duplicati liste diverse o per confrontare i valori di due liste.

Li useremo in un esempio qui sotto.

Stringhe

Le stringhe sono liste di caratteri immutabili e con un set di funzioni specifico. Immutabili significa che se modifichiamo una stringa in realtà Python crea una copia della stringa con le modifiche (che possiamo riassegnare alla stessa variabile).

saluto = "Ciao"
nome = 'Mario'

# Le triple virgolette servono per testi su più righe
testo_lungo = """Questa è una stringa
che occupa più righe."""

Possiamo usare la formattazione f per creare stringhe:

saluto = f'{saluto} {nome}' # "Ciao Mario"

In lettura si comportano come le liste, con indici e slicing e ciclo for:

parola = "Python"

print(parola[0])   # 'P' (primo carattere)
print(parola[-1])  # 'n' (ultimo carattere, indice negativo)

# Slicing: [inizio:fine]
print(parola[1:4]) # 'yth' (dal 2° al 5° carattere, escludendo il 4°)

for c in parola:
   print(c) # stampa un carattere alla volta

Va però ricordata l’immutabilità:

parola[3] = 'y' # da errore

Sono possibili svariate operazioni sulle stringhe:

MetodoCosa faEsempio
upper() / lower()Maiuscole/minuscole"ciao".upper() → 'CIAO'
strip()Rimuove spazi bianchi ai bordi" testo ".strip() → 'testo'
split(sep)Divide la stringa in una lista"A,B".split(",") → ['A', 'B']
replace(a, b)Sostituisce un testo con un altro"ciao".replace("a", "e") → 'cieo'
inCerca se un testo è presente"c" in "ciao" → True
find(x) Cerca se un testo è presente e restituisce la posizione"ciao".find('c') → 0

Vediamo un esempio che unisce proprio stringhe e set.

preferenze = []

num_amici = int(input("Quanti amici vuoi includere? "))

for i in range(num_amici):
    nome_amico = input(f"Inserisci il nome dell'amico numero {i + 1}: ")
    print(f"Inserisci i cibi preferiti di {nome_amico} (separati da spazi):")
    preferenze_cibo = set(input().split()) # prima dividiamo i cibi in singole stringhe e poi creiamo un set
        
    preferenze.append(preferenze_cibo) # aggiungiamo il set alla lista

if num_amici > 0:
  cibi_in_comune = set(preferenze[0]) 
  cibi_i_cibi = set(preferenze[0])

for elenco_cibi in preferenze[1:]:
    cibi_in_comune = cibi_in_comune & elenco_cibi # intersezione
    tutti_i_cibi = cibi_in_comune | elenco_cibi # unione

# Stampa dei risultati
print("\nCibi comuni a tutti gli amici:", cibi_in_comune)
print("Tutti i cibi preferiti dagli amici:", tutti_i_cibi)

Dizionari

Un dizionario, o array associativo, è una collezione di coppie chiave-valore, dove le chiavi permettono di accedere al singolo elemento della collezione, senza doverla scorrere come avviene con le liste. Essi sono definiti tramite parentesi graffe {} identificatori : e separatori ,

Ad esempio:

person = {
  "nome": "Mario",
  "cognome": "Rossi",
  "età": 28,
  "sposato": True
}

empty_dict = {}
empty_dict2 = dict()

I dizionari sono dinamici, è quindi possibile modificare, aggiungere ed eliminare elementi. Si accede ai singoli elementi usando l’operatore [] :

person["address"] = "Via Roma 23"
print(person["età"])

I dizionari sono chiamati in questo modo perché il loro funzionamento ricorda proprio quello del vocabolario, in cui accediamo al singolo lemma tramite appunto la parola chiave.

Alcune note:

  • le chiavi di norma sono delle stringhe, ma è possibile usare int oppure anche tuple (che devono contenere int o stringhe)
  • le chiavi devono essere diverse tra loro (cioè nel loro insieme formano un set)

La loro utilità è che consentono di rappresentare, in una variabile, collezioni dati che hanno una struttura definita, ovvero le caratteristiche di un oggetto unico con diversi attributi, come una persona, un immobile, un movimento finanziario, un prodotto in vendita, ecc.

Qui le funzioni più importanti:

MetodoDescrizione
len(d)Restituisce il numero di elementi
d.keys()Restituisce le chiavi (oggetto view)
d.values()Restituisce i valori (oggetto view)
d.items()Restituisce coppie (chiave, valore) (oggetto view)
d.get(k, default)Legge con fallback sicuro
d.pop(k[, default])Rimuove e restituisce il valore

Vediamo degli esempi:

utenti = {
    "Mario": "admin",
    "Sandro": "user",
    "Francesca": "guest"
}

print(len(utenti)) # 3

chiavi = utenti.keys()
print(list(chiavi)) # ['Mario', 'Sandro', 'Francesca']

ruoli = utenti.values()
print(list(ruoli)) # ["admin", "user", "guest"]

for nome, ruolo in utenti.items():
    print(f"{nome} è un {ruolo}") 

# Mario è un admin
# Sandro è un user
# Francesca è un guest

print(utenti.get("Davide", "ospite"))  # scrive "ospite" perché Davide non c'è

ruolo_rimosso = utenti.pop("Sandro") # rimuove l'elemento con quella chiave

Esempio:

inventario = {
    "laptop": {"prezzo": 900, "quantità": 5},
    "mouse": {"prezzo": 25, "quantità": 10},
    "tablet": {"prezzo": 450, "quantità": 8},
    "monitor": {"prezzo": 200, "quantità": 3}
}
fine = False
while not fine:
  print('''\nMenu
  1: mostra prodotti
  2: acquista
  0: esci''')
  scelta = int(input("Inserisci scelta: "))
  if scelta == 0:
    fine = True
  elif scelta == 1:
    print("NOME\tPREZZO\tQUANTITA'")
    for nome, prodotto in inventario.items():
      print(f"{nome}\t{prodotto["prezzo"]}\t{prodotto["quantità"]}")
  elif scelta == 2:
    nome_prodotto = input("Inserisci nome prodotto: ")
    if nome_prodotto not in inventario:
      print("Prodotto non in inventario.\n")
    else: 
      if inventario[nome_prodotto]["quantità"] == 0:
        print("Prodotto terminato.\n")
      else: 
        inventario[nome_prodotto]["quantità"] -= 1

Conclusioni

Le liste rappresentano la struttura “base” con cui lavorare su collezioni di oggetti. Python però offre strutture adatte per scenari differenti:

  • tuple: liste non modificabili
  • set: insiemi non ordinati ma con valori unici
  • dizionari: collezioni di coppie chiave valore

Nella maggior parte dei progetti si usano liste e dizionari, con situazioni specifiche dove si usano le tuple e i set.