Skip to content
> 💻 🧠 Codice 1001 > 📚 Materiali di Apprendimento > 🐍 Python > 📘 Collezioni in Python

📘 Collezioni in Python

In Python, una collezione è un oggetto che contiene un gruppo di elementi e permette di manipolarli come un’unità unica.

Le collezioni in genere supportano:

  • iterazione (for elemento in collezione)
  • verifica di appartenenza (x in collezione)
  • determinazione della lunghezza (len(collezione))
  • accesso tramite indice o chiave (se ordinata o associativa)

Python non ha un’«interfaccia collezione» rigorosa, ma segue protocolli informali. Se un oggetto implementa __iter__, __len__, __contains__, può essere considerato una collezione.


Cosa NON è una collezione

I seguenti tipi non sono collezioni, poiché non contengono gruppi di elementi:

  • int, float, bool — valori scalari
  • None — assenza di valore
  • funzioni, moduli, classi — sono oggetti, ma non contenitori di dati (a meno che non contengano __dict__)

Collezioni integrate

Disponibili senza import:

TipoDescrizione
listSequenza ordinata, modificabile.
tupleSequenza ordinata, immutabile.
dictMappatura chiave-valore ordinata (da Python 3.7).
setCollezione non ordinata di elementi unici.
frozensetVersione immutabile di set.

Collezioni estese dalla libreria standard

TipoModuloScopo
SimpleNamespacetypesOggetto con attributi dinamici (alternativa al dict con accesso tramite .).
namedtuplecollectionsTupla immutabile con campi nominati.
dequecollectionsCoda a doppia estremità — efficiente per aggiunte/rimozioni a entrambe le estremità.
CountercollectionsSottoclasse di dict per contare oggetti hashabili.
defaultdictcollectionsDizionario con valori predefiniti per chiavi mancanti.
dataclassdataclassesGenera automaticamente __init__, __repr__, __eq__, ecc.
UserListcollectionsClasse base per oggetti tipo lista personalizzati.
UserDictcollectionsClasse base per oggetti tipo dizionario personalizzati.

Altri tipi simili alle collezioni

Anche se non sempre chiamati “collezioni”, questi tipi rappresentano o memorizzano gruppi di dati.

1. str — stringa

Sequenza ordinata, immutabile di caratteri.

s = "Python"
print(len(s))        # → 6
print(s[0])          # → P
print('y' in s)      # → True
print(list(s))       # → ['P', 'y', 't', 'h', 'o', 'n']

2. bytes, bytearray

  • bytes — sequenza immutabile di byte.
  • bytearray — versione modificabile.
b = b"ciao"
print(b[0])          # → 99
print(len(b))        # → 4

ba = bytearray(b"ciao")
ba[0] = 72
print(ba)            # → bytearray(b'Hiao')

3. range

Sequenza numerica lazy, ordinata. Non memorizza gli elementi in memoria.

r = range(3)
print(list(r))       # → [0, 1, 2]
print(1 in r)        # → True
print(r[2])          # → 2

4. array.array

Memorizza dati numerici omogenei in modo compatto (come in C).

from array import array
arr = array('i', [1, 2, 3])  # 'i' = intero con segno
print(arr)                   # → array('i', [1, 2, 3])

5. Generatori e iteratori

Non memorizzano dati — li generano su richiesta. Non supportano len() né indicizzazione.

gen = (x * 2 for x in range(3))
print(list(gen))     # → [0, 2, 4]
# len(gen) → TypeError

6. ChainMap (da collections)

Raggruppa più dizionari in un’unica vista — la ricerca attraversa le mappe in ordine.

from collections import ChainMap

d1 = {'a': 1}
d2 = {'b': 2}
cm = ChainMap(d1, d2)
print(cm['a'])       # → 1
print(cm['b'])       # → 2

7. OrderedDict (da collections)

Dizionario che mantiene l’ordine di inserimento. Rilevante per Python < 3.7.

from collections import OrderedDict

od = OrderedDict([('a', 1), ('b', 2)])
print(od)            # → OrderedDict([('a', 1), ('b', 2)])

8. enum.Enum, enum.Flag

Collezioni di costanti nominate.

from enum import Enum

class Colore(Enum):
    ROSSO = 1
    VERDE = 2

print(list(Colore))   # → [<Colore.ROSSO: 1>, <Colore.VERDE: 2>]

9. typing.NamedTuple, typing.TypedDict

Wrapper tipizzati su namedtuple e dict.

from typing import NamedTuple, TypedDict

class Persona(NamedTuple):
    nome: str
    età: int

p = Persona("Giulia", 25)

class Film(TypedDict):
    titolo: str
    anno: int

m: Film = {"titolo": "Matrix", "anno": 1999}

10. heapq, bisect — strumenti, non collezioni

Lavorano con collezioni, ma non lo sono:

  • heapq — algoritmo coda di priorità tramite liste.
  • bisect — mantiene ordine in liste ordinate.

1. Liste — list

Collezione ordinata, modificabile. Gli elementi possono ripetersi, tutti i tipi sono ammessi.

Usata quando serve una sequenza flessibile: aggiungere, rimuovere, modificare elementi.

Creazione: []

marco_list = ["Marco", "Roma", 30, "ingegnere"]
print(f"Creazione lista: {marco_list}")
# → Creazione lista: ['Marco', 'Roma', 30, 'ingegnere']

print(f"Elemento all’indice 0: {marco_list[0]}")
# → Elemento all’indice 0: Marco

marco_list[2] = 31
print(f"Dopo modifica: {marco_list}")
# → Dopo modifica: ['Marco', 'Roma', 31, 'ingegnere']

marco_list.append("sposato")
print(f"Dopo append: {marco_list}")
# → Dopo append: ['Marco', 'Roma', 31, 'ingegnere', 'sposato']

marco_list.insert(1, "Italia")
print(f"Dopo insert: {marco_list}")
# → Dopo insert: ['Marco', 'Italia', 'Roma', 31, 'ingegnere', 'sposato']

marco_list.remove("ingegnere")
print(f"Dopo remove per valore: {marco_list}")
# → Dopo remove per valore: ['Marco', 'Italia', 'Roma', 31, 'sposato']

del marco_list[2]
print(f"Dopo cancellazione per indice: {marco_list}")
# → Dopo cancellazione per indice: ['Marco', 'Italia', 31, 'sposato']

marco_list.extend(["hobby", "pesca"])
print(f"Dopo extend: {marco_list}")
# → Dopo extend: ['Marco', 'Italia', 31, 'sposato', 'hobby', 'pesca']

marco_list.pop()
print(f"Dopo pop: {marco_list}")
# → Dopo pop: ['Marco', 'Italia', 31, 'sposato', 'hobby']

2. Dizionari — dict

Collezione di coppie chiave → valore. Le chiavi devono essere hashabili. Da Python 3.7, l’ordine di inserimento è preservato.

Utile per dati strutturati: profili, configurazioni, JSON.

Creazione: {}

giulia_dict = {"nome": "Giulia", "età": 25, "città": "Firenze", "professione": "artista"}
print(f"Creazione dict: {giulia_dict}")
# → Creazione dict: {'nome': 'Giulia', 'età': 25, 'città': 'Firenze', 'professione': 'artista'}

print(f"Valore per chiave 'nome': {giulia_dict['nome']}")
# → Valore per chiave 'nome': Giulia

giulia_dict["età"] = 26
print(f"Dopo aggiornamento: {giulia_dict}")
# → Dopo aggiornamento: {'nome': 'Giulia', 'età': 26, 'città': 'Firenze', 'professione': 'artista'}

giulia_dict["hobby"] = "pittura"
print(f"Dopo aggiunta coppia: {giulia_dict}")
# → Dopo aggiunta coppia: {'nome': 'Giulia', 'età': 26, 'città': 'Firenze', 'professione': 'artista', 'hobby': 'pittura'}

del giulia_dict["città"]
print(f"Dopo cancellazione coppia: {giulia_dict}")
# → Dopo cancellazione coppia: {'nome': 'Giulia', 'età': 26, 'professione': 'artista', 'hobby': 'pittura'}

hobby = giulia_dict.pop("hobby")
print(f"Dopo pop: {giulia_dict}, valore: {hobby}")
# → Dopo pop: {'nome': 'Giulia', 'età': 26, 'professione': 'artista'}, valore: pittura

print(f"Chiave 'nome' esiste: {'nome' in giulia_dict}")
# → Chiave 'nome' esiste: True

3. Tuple — tuple

Collezione ordinata, immutabile. Adatta a dati fissi.

Usata quando l’immutabilità è importante: coordinate, parametri, valori di ritorno.

Creazione: ()

marco_tuple = ("Marco", "Roma", 30, "ingegnere")
print(f"Creazione tupla: {marco_tuple}")
# → Creazione tupla: ('Marco', 'Roma', 30, 'ingegnere')

print(f"Elemento all’indice 2: {marco_tuple[2]}")
# → Elemento all’indice 2: 30

# marco_tuple[0] = "Luca"  → TypeError
# marco_tuple.append("qualcosa") → AttributeError
  • Le tuple consumano meno memoria e sono più veloci delle liste.
  • Ideali quando la modificabilità non serve.

4. SimpleNamespace

Classe semplice da types per creare oggetti con attributi dinamici. Accesso tramite notazione a punto (obj.attr).

Utile quando si vuole la sintassi obj.nome senza definire una classe completa.

from types import SimpleNamespace

giulia_ns = SimpleNamespace(nome="Giulia", età=25, città="Firenze")
print(f"Oggetto: {giulia_ns}")
# → Oggetto: namespace(nome='Giulia', età=25, città='Firenze')

print(f"Nome: {giulia_ns.nome}")
# → Nome: Giulia

giulia_ns.età = 26
print(f"Dopo aggiornamento: {giulia_ns}")
# → Dopo aggiornamento: namespace(nome='Giulia', età=26, città='Firenze')

giulia_ns.professione = "artista"
print(f"Con nuovo attributo: {giulia_ns}")
# → Con nuovo attributo: namespace(nome='Giulia', età=26, città='Firenze', professione='artista')

del giulia_ns.città
print(f"Dopo cancellazione: {giulia_ns}")
# → Dopo cancellazione: namespace(nome='Giulia', età=26, professione='artista')

setattr(giulia_ns, "hobby", "pittura")
print(f"Tramite setattr: {giulia_ns}")
# → Tramite setattr: namespace(nome='Giulia', età=26, professione='artista', hobby='pittura')

delattr(giulia_ns, "hobby")
print(f"Tramite delattr: {giulia_ns}")
# → Tramite delattr: namespace(nome='Giulia', età=26, professione='artista')
  • Alternativa al dict quando obj.nome è preferibile a obj['nome'].

5. Insiemi — set

Collezione non ordinata di elementi unici. Supporta operazioni insiemistiche: unione, intersezione, differenza.

Usata per rimuovere duplicati e verificare appartenenza.

Creazione: {} o set()

numeri = {1, 2, 3, 3, 2, 1}
print(f"Insieme: {numeri}")
# → Insieme: {1, 2, 3}

numeri.add(4)
print(f"Dopo aggiunta: {numeri}")
# → Dopo aggiunta: {1, 2, 3, 4}

numeri.remove(2)
print(f"Dopo rimozione: {numeri}")
# → Dopo rimozione: {1, 3, 4}

altro = {3, 4, 5}
print(f"Unione: {numeri | altro}")
# → Unione: {1, 3, 4, 5}

print(f"Intersezione: {numeri & altro}")
# → Intersezione: {3, 4}

print(f"Differenza: {numeri - altro}")
# → Differenza: {1}

6. Insiemi immutabili — frozenset

Versione immutabile di set. Può essere usata come chiave di dict o elemento di un altro insieme.

frozen = frozenset([1, 2, 3, 2])
print(f"frozenset: {frozen}")
# → frozenset: frozenset({1, 2, 3})

altro = frozenset([3, 4])
print(f"Intersezione: {frozen & altro}")
# → Intersezione: frozenset({3})

print(f"Unione: {frozen | altro}")
# → Unione: frozenset({1, 2, 3, 4})

# frozen.add(5) → AttributeError

7. namedtuple — tuple nominate

Struttura immutabile con accesso per nome di campo. Più leggibile delle tuple classiche.

from collections import namedtuple

Persona = namedtuple("Persona", ["nome", "età", "città"])
giulia = Persona("Giulia", 25, "Firenze")

print(f"Oggetto: {giulia}")
# → Oggetto: Persona(nome='Giulia', età=25, città='Firenze')

print(f"Nome: {giulia.nome}")
# → Nome: Giulia

print(f"Età: {giulia[1]}")
# → Età: 25

# giulia.età = 26 → AttributeError

giulia_nuova = giulia._replace(età=26)
print(f"Copia modificata: {giulia_nuova}")
# → Copia modificata: Persona(nome='Giulia', età=26, città='Firenze')
  • Ideale per record: punti, utenti, configurazioni — quando contano immutabilità e leggibilità.

8. deque — coda a doppia estremità

Ottimizzata per aggiunte/rimozioni veloci a entrambe le estremità. Più efficiente di list per appendleft, popleft.

from collections import deque

d = deque([1, 2, 3])
print(f"deque iniziale: {d}")
# → deque iniziale: deque([1, 2, 3])

d.appendleft(0)
print(f"Dopo appendleft: {d}")
# → Dopo appendleft: deque([0, 1, 2, 3])

d.append(4)
print(f"Dopo append: {d}")
# → Dopo append: deque([0, 1, 2, 3, 4])

sinistra = d.popleft()
print(f"Dopo popleft: {sinistra}, rimanente: {d}")
# → Dopo popleft: 0, rimanente: deque([1, 2, 3, 4])

destra = d.pop()
print(f"Dopo pop: {destra}, rimanente: {d}")
# → Dopo pop: 4, rimanente: deque([1, 2, 3])
  • Usata in algoritmi: BFS, cache LRU, buffer — quando le operazioni alle estremità devono essere veloci.

9. Counter — contatore di elementi

Conta la frequenza degli elementi in un iterabile. Utile per statistiche e analisi.

from collections import Counter

testo = "abracadabra"
c = Counter(testo)
print(f"Conteggio lettere: {c}")
# → Conteggio lettere: Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1})

print(f"Frequenza di 'a': {c['a']}")
# → Frequenza di 'a': 5

print(f"Top 3: {c.most_common(3)}")
# → Top 3: [('a', 5), ('b', 2), ('r', 2)]

c2 = Counter("bukva")
c.update(c2)
print(f"Dopo update: {c}")
# → Dopo update: Counter({'a': 6, 'b': 3, 'r': 2, 'c': 1, 'd': 1, 'u': 1, 'k': 1, 'v': 1})
  • Utile per analisi testi, log, votazioni — ovunque serva contare «cosa appare più spesso».

10. defaultdict — dizionario con valori predefiniti

Crea automaticamente valori predefiniti per chiavi mancanti. Elimina verifiche if key in dict.

from collections import defaultdict

dd_list = defaultdict(list)
dd_list["frutti"].append("mela")
dd_list["frutti"].append("banana")
print(f"Lista: {dict(dd_list)}")
# → Lista: {'frutti': ['mela', 'banana']}

dd_int = defaultdict(int)
for char in "abracadabra":
    dd_int[char] += 1
print(f"Conteggi: {dict(dd_int)}")
# → Conteggi: {'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1}

dd_set = defaultdict(set)
dd_set["città"].add("Roma")
dd_set["città"].add("Firenze")
print(f"Insieme: {dict(dd_set)}")
# → Insieme: {'città': {'Roma', 'Firenze'}}
  • Elimina codice ripetitivo come if key not in d: d[key] = [].
  • Rende il codice più pulito e sicuro.

11. dataclass — classi dati

Decoratore che genera automaticamente __init__, __repr__, __eq__, ecc.

from dataclasses import dataclass

@dataclass
class Persona:
    nome: str
    età: int
    città: str = "Non specificata"

giulia = Persona("Giulia", 25)
print(f"Oggetto: {giulia}")
# → Oggetto: Persona(nome='Giulia', età=25, città='Non specificata')

print(f"Nome: {giulia.nome}")
# → Nome: Giulia

giulia.età = 26
print(f"Dopo aggiornamento: {giulia}")
# → Dopo aggiornamento: Persona(nome='Giulia', età=26, città='Non specificata')

bob = Persona("Bob", 30)
print(f"Giulia == Bob: {giulia == bob}")
# → Giulia == Bob: False

@dataclass(frozen=True)
class PersonaImmutabile:
    nome: str
    età: int

ivan = PersonaImmutabile("Ivan", 40)
# ivan.età = 41 → FrozenInstanceError
  • Sostituisce la scrittura manuale di __init__, __repr__, __eq__.
  • Ideale per DTO, configurazioni, modelli.

12. UserList — liste personalizzate

Eredita da collections.UserList. Usata per creare liste con comportamento personalizzato.

from collections import UserList

class ListaConLog(UserList):
    def append(self, item):
        print(f"[LOG] Aggiunta: {item}")
        super().append(item)

    def remove(self, item):
        print(f"[LOG] Rimozione: {item}")
        super().remove(item)

log_list = ListaConLog([1, 2, 3])
print(f"Iniziale: {log_list}")
# → Iniziale: [1, 2, 3]

log_list.append(4)
# → [LOG] Aggiunta: 4
print(f"Dopo append: {log_list}")
# → Dopo append: [1, 2, 3, 4]

log_list.remove(2)
# → [LOG] Rimozione: 2
print(f"Dopo remove: {log_list}")
# → Dopo remove: [1, 3, 4]
  • Utile per aggiungere log, validazioni, o modificare il comportamento standard delle liste.

13. UserDict — dizionari personalizzati

Eredita da collections.UserDict. Usata per creare dizionari con comportamento personalizzato.

from collections import UserDict

class DictChiaviMinuscole(UserDict):
    def __setitem__(self, key, value):
        key = key.lower() if isinstance(key, str) else key
        super().__setitem__(key, value)

    def __getitem__(self, key):
        key = key.lower() if isinstance(key, str) else key
        return super().__getitem__(key)

ld = DictChiaviMinuscole()
ld["Nome"] = "Giulia"
print(f"Valore per 'Nome': {ld['Nome']}")
# → Valore per 'Nome': Giulia
print(f"Valore per 'nome': {ld['nome']}")
# → Valore per 'nome': Giulia
print(f"Chiavi: {list(ld.keys())}")
# → Chiavi: ['nome']
  • Usata per normalizzare chiavi, validare, loggare, fare caching, ecc.

📈 Confronto memoria e prestazioni

La scelta della collezione influenza prestazioni e consumo di memoria. Di seguito benchmark pratici.


1. Memoria: list vs tuple vs array.array

import sys
from array import array

n = 1_000_000
data = list(range(n))
data_t = tuple(range(n))
data_a = array('i', range(n))

print(f"list:  {sys.getsizeof(data) / 1024 / 1024:.2f} MB")
# → list:  8.00 MB

print(f"tuple: {sys.getsizeof(data_t) / 1024 / 1024:.2f} MB")
# → tuple: 8.00 MB

print(f"array: {sys.getsizeof(data_a) / 1024 / 1024:.2f} MB")
# → array: 3.81 MB
  • array.array usa ~2x meno memoria per numeri.
  • list e tuple consumano memoria simile, ma tuple è leggermente più veloce in iterazione.

2. Velocità di accesso: list vs tuple vs array.array

import time

def time_access(collection, name):
    start = time.perf_counter()
    total = 0
    for i in range(len(collection)):
        total += collection[i]
    end = time.perf_counter()
    print(f"{name}: {end - start:.4f} secondi")

n = 10_000_000
lst = list(range(n))
tpl = tuple(range(n))
arr = array('i', range(n))

time_access(lst, "list")   # → list: 1.2000 secondi
time_access(tpl, "tuple")  # → tuple: 1.0000 secondi
time_access(arr, "array")  # → array: 0.8000 secondi
  • array.array è il più veloce per dati numerici.
  • tuple è 10–20% più veloce di list.
  • La differenza è evidente su larga scala.

3. Memoria: dict vs SimpleNamespace vs dataclass

d = {"nome": "A", "età": 25, "città": "X", "hobby": "Y", "lavoro": "Z"}
ns = SimpleNamespace(nome="A", età=25, città="X", hobby="Y", lavoro="Z")
dc = PersonaDC("A", 25, "X", "Y", "Z")

print(f"dict:      {sys.getsizeof(d)} byte")          # → 232
print(f"SimpleNamespace: {sys.getsizeof(ns)} byte")   # → 64
print(f"dataclass: {sys.getsizeof(dc)} byte")         # → 64
print(f"ns.__dict__: {sys.getsizeof(ns.__dict__)} byte")  # → 232
  • SimpleNamespace e dataclass consumano tanta memoria quanto dict a causa di __dict__.
  • Usa __slots__ per risparmiare memoria.

4. Ottimizzazione memoria: dataclass con __slots__

@dataclass
class PersonaSlots:
    __slots__ = ("nome", "età", "città", "hobby", "lavoro")
    nome: str
    età: int
    città: str
    hobby: str
    lavoro: str

dc_slots = PersonaSlots("A", 25, "X", "Y", "Z")
print(f"dataclass + slots: {sys.getsizeof(dc_slots)} byte")
# → 80 byte

# dc_slots.nuovo = "valore" → AttributeError
  • __slots__ risparmia memoria e accelera l’accesso agli attributi.
  • Contropartita: non si possono aggiungere attributi dinamici.

5. Velocità di ricerca: list vs set

n = 1_000_000
lst = list(range(n))
st = set(range(n))

def time_in(collection, target, name):
    start = time.perf_counter()
    for _ in range(1000):
        _ = target in collection
    end = time.perf_counter()
    print(f"{name} (ricerca {target}): {end - start:.4f} secondi")

time_in(lst, 999_999, "list")   # → 10.0000 secondi
time_in(st, 999_999, "set")     # → 0.0005 secondi
  • set è migliaia di volte più veloce di list per verifiche di appartenenza.
  • Usa sempre set per verifiche frequenti di x in collection.

6. Memoria: set vs frozenset

s = set(range(1000))
fs = frozenset(range(1000))

print(f"set:       {sys.getsizeof(s)} byte")     # → 32792
print(f"frozenset: {sys.getsizeof(fs)} byte")   # → 32792
  • frozenset e set consumano memoria identica.
  • La differenza è solo l’immutabilità.

7. Velocità di aggiunta: list.append vs deque.append vs deque.appendleft

from collections import deque
import time

def time_append(collection, n, method='append'):
    start = time.perf_counter()
    for i in range(n):
        if method == 'appendleft' and hasattr(collection, 'appendleft'):
            collection.appendleft(i)
        else:
            collection.append(i)
    end = time.perf_counter()
    return end - start

n = 100_000

lst = []
dq = deque()

time_list_append = time_append(lst, n)              # → 0.0100 secondi
time_deque_append = time_append(dq, n)              # → 0.0100 secondi
time_deque_appendleft = time_append(deque(), n, 'appendleft')  # → 0.0100 secondi

# list.insert(0):
lst = []
start = time.perf_counter()
for i in range(n):
    lst.insert(0, i)
end = time.perf_counter()
print(f"list.insert(0):   {end - start:.4f} secondi")   # → 5.0000 secondi
  • deque.appendleft è O(1), a differenza di list.insert(0) che è O(n).
  • Usa deque per operazioni frequenti a entrambe le estremità.

🧠 Raccomandazioni prestazioni

SituazioneUsareMotivo
Memorizzare numeri, memoria criticaarray.array2x meno memoria, accesso più veloce
Dati immutabilituplePiù veloce di list, più sicuro
Verifiche frequenti x in collectionset / frozensetO(1) vs O(n) di list
Operazioni a entrambe le estremitàdequeappendleft/popleft in O(1)
Dati strutturati, memoria criticadataclass + __slots__Nessun __dict__, meno memoria
Contare frequenzeCounterOttimizzato per questo compito
Comportamento personalizzatoUserList / UserDictEstensione sicura delle collezioni integrate

📊 Confronto collezioni

TipoOrdinatoModificabileElementi uniciAccesso indiceDuplicati
list✅ Sì✅ Sì❌ No✅ Sì✅ Sì
tuple✅ Sì❌ No❌ No✅ Sì✅ Sì
dict✅ Sì*✅ SìSolo chiavi❌ NoValori: ✅
set❌ No✅ Sì✅ Sì❌ No❌ No
frozenset❌ No❌ No✅ Sì❌ No❌ No
SimpleNamespace✅ Sì (attr)✅ Sì❌ No (attr possono ripetersi semanticamente)❌ No✅ Sì
namedtuple✅ Sì❌ No❌ No✅ Sì✅ Sì
deque✅ Sì✅ Sì❌ No✅ Sì✅ Sì
Counter❌ No✅ Sì❌ No❌ No (ma ha chiavi)✅ Sì
defaultdict✅ Sì*✅ SìSolo chiavi❌ NoValori: ✅
dataclass✅ Sì (campi)✅ Sì (se non frozen)❌ No❌ No✅ Sì
UserList✅ Sì✅ Sì❌ No✅ Sì✅ Sì
UserDict✅ Sì*✅ SìSolo chiavi❌ NoValori: ✅
str✅ Sì❌ No❌ No✅ Sì✅ Sì
bytes✅ Sì❌ No❌ No✅ Sì✅ Sì
bytearray✅ Sì✅ Sì❌ No✅ Sì✅ Sì
range✅ Sì❌ No❌ No✅ Sì❌ No
array.array✅ Sì✅ Sì❌ No✅ Sì✅ Sì
ChainMap✅ Sì*✅ SìSolo chiavi❌ NoValori: ✅
Enum✅ Sì❌ No✅ Sì (membri)❌ No❌ No
  • — da Python 3.7, dict, defaultdict, UserDict, ChainMap mantengono l’ordine di inserimento.

💡 Quando usare cosa?

CompitoCollezione
Sequenza modificabilelist / deque / UserList / bytearray
Dati immutabilituple / namedtuple / frozenset / str / bytes
Ricerca veloce, rimozione duplicatiset / frozenset
Dati strutturatidict / dataclass / SimpleNamespace / UserDict / TypedDict
Usabile come chiave di dictfrozenset
Oggetti temporanei con accesso tramite .SimpleNamespace / dataclass
Contare frequenzeCounter
Valori predefiniti per chiavidefaultdict
Operazioni efficienti alle estremitàdeque
Comportamento personalizzato listaUserList
Comportamento personalizzato dictUserDict
Dati binaribytes / bytearray / array.array
Configurazioni con gerarchiaChainMap
Costanti nominateEnum
Sequenze lazyrange / generatori

Leave a Reply

Your email address will not be published. Required fields are marked *