Ordinare le Liste
Impara a ordinare le liste Python con sorted() e sort(), usa il parametro key, ordina in modo inverso e gestisci oggetti personalizzati con esempi chiari.
Ordinare una lista è una delle operazioni più comuni in Python. Python offre due strumenti integrati per farlo: la funzione sorted(), che restituisce una nuova lista ordinata senza modificare l'originale, e il metodo list.sort(), che riordina la lista in-place. Entrambi accettano un flag reverse per l'ordine decrescente e un parametro key per la logica di ordinamento personalizzata.
Questo capitolo tratta:
sorted()— ordina qualsiasi iterabile in una nuova listalist.sort()— ordina una lista in-place- Ordinamento in senso crescente e decrescente
- Il parametro
key— ordina per lunghezza, campo o qualsiasi criterio personalizzato - Ordinamento senza distinzione tra maiuscole e minuscole
- Ordinamento di liste di dizionari e oggetti personalizzati
- Ordinamento multi-chiave
operator.itemgettercome alternativa efficiente alle lambda
Per un ripasso sui fondamentali delle liste, consulta i capitoli Python Lists e List Methods.
La Funzione sorted()
sorted() accetta qualsiasi iterabile (lista, tupla, string, …) e restituisce una nuova lista ordinata nuova. L'iterabile originale rimane invariato.
Sintassi:
sorted(iterable, *, key=None, reverse=False)iterable— la sequenza da ordinarekey— una funzione opzionale a un argomento applicata a ciascun elemento prima del confronto (default: confronta gli elementi direttamente)reverse— impostare aTrueper ordinare in senso decrescente (default:False)
Ordinare una lista di stringhe
Ordinare una lista di numeri
Le liste numeriche vengono ordinate per grandezza, non per rappresentazione string (quindi 10 non viene ordinato prima di 9).
nums = [3, 1, 4, 1, 5, 9, 2, 6]
print(sorted(nums))
# [1, 1, 2, 3, 4, 5, 6, 9]Ordinare in senso decrescente con reverse=True
Passa reverse=True per ottenere prima i valori più grandi.
nums = [3, 1, 4, 1, 5, 9, 2, 6]
print(sorted(nums, reverse=True))
# [9, 6, 5, 4, 3, 2, 1, 1]Il Metodo list.sort()
list.sort() riordina la lista in-place e restituisce sempre None. Usalo quando non hai più bisogno dell'ordine originale e vuoi evitare il sovraccarico di memoria di una seconda lista.
Sintassi:
list.sort(*, key=None, reverse=False)I parametri sono identici a quelli di sorted().
Ordinare una lista in-place
Ordinare in senso decrescente
sort() restituisce None — un errore comune
Un errore frequente è assegnare il risultato di sort() a una variabile:
fruits = ['banana', 'apple', 'cherry']
result = fruits.sort() # sort() modifies fruits, returns None
print(result) # None ← not the sorted list!
print(fruits) # ['apple', 'banana', 'cherry'] ← fruits was modifiedSe hai bisogno sia del risultato ordinato che dell'ordine originale, usa invece sorted().
sorted() vs list.sort() — Quando Usare Quale
sorted() | list.sort() | |
|---|---|---|
| Restituisce | Una nuova lista ordinata | None |
| Lista originale | Invariata | Modificata in-place |
| Funziona su | Qualsiasi iterabile | Solo liste |
| Memoria | Usa memoria aggiuntiva | Nessuna lista extra |
Usa sorted() quando hai bisogno dell'originale invariato, o quando ordini una tupla o un altro iterabile.
Usa list.sort() quando hai una lista, vuoi ordinarla in-place e l'efficienza della memoria è importante.
Ordinamento con il Parametro key
Il parametro key accetta un callable a un argomento. Python lo chiama una volta su ciascun elemento e usa il valore restituito per i confronti. Questo evita la duplicazione dei dati e rende l'ordinamento flessibile.
Ordinare per lunghezza della stringa
words = ['banana', 'apple', 'cherry', 'kiwi']
print(sorted(words, key=len))
# ['kiwi', 'apple', 'banana', 'cherry']len viene passato direttamente — non serve una lambda quando si usa una funzione integrata che accetta un argomento.
Ordinare una lista di tuple per un campo specifico
La lambda lambda x: x[1] estrae il secondo elemento (il numero) da ciascuna tupla, così Python confronta numeri invece di tuple intere.
Ordinare una lista di dizionari
students = [
{'name': 'Charlie', 'grade': 85},
{'name': 'Alice', 'grade': 92},
{'name': 'Bob', 'grade': 78},
]
by_grade = sorted(students, key=lambda s: s['grade'])
for s in by_grade:
print(s['name'], s['grade'])
# Bob 78
# Charlie 85
# Alice 92Per ordinare in senso decrescente (voto più alto prima), aggiungi reverse=True:
by_grade_desc = sorted(students, key=lambda s: s['grade'], reverse=True)
for s in by_grade_desc:
print(s['name'], s['grade'])
# Alice 92
# Charlie 85
# Bob 78Ordinamento senza distinzione tra maiuscole e minuscole
Per default, l'ordinamento di Python è sensibile alle maiuscole: tutte le lettere maiuscole vengono prima delle minuscole perché hanno code point Unicode più bassi. Usa key=str.lower per ordinare indipendentemente dal caso.
words = ['Banana', 'apple', 'Cherry', 'date']
print(sorted(words)) # case-sensitive (uppercase first)
# ['Banana', 'Cherry', 'apple', 'date']
print(sorted(words, key=str.lower)) # case-insensitive
# ['apple', 'Banana', 'Cherry', 'date']Utilizzo di operator.itemgetter e operator.attrgetter
Il modulo operator fornisce alternative più veloci alle lambda per i pattern di chiave più comuni.
operator.itemgetter — per sequenze e dizionari
import operator
fruits = [('apple', 10), ('banana', 5), ('cherry', 20)]
print(sorted(fruits, key=operator.itemgetter(1)))
# [('banana', 5), ('apple', 10), ('cherry', 20)]operator.itemgetter(1) è equivalente a lambda x: x[1] ma è implementato in C e risulta più veloce su liste di grandi dimensioni.
operator.attrgetter — per gli oggetti
import operator
class Student:
def __init__(self, name, grade):
self.name = name
self.grade = grade
def __repr__(self):
return f'Student({self.name!r}, {self.grade})'
students = [Student('Charlie', 85), Student('Alice', 92), Student('Bob', 78)]
print(sorted(students, key=operator.attrgetter('grade')))
# [Student('Bob', 78), Student('Charlie', 85), Student('Alice', 92)]Ordinamento Multi-Chiave
Restituisci una tupla dalla funzione key per ordinare secondo più criteri. Python confronta le tuple elemento per elemento, quindi i pareggi sulla prima chiave passano alla seconda.
# Sort by grade ascending, then by name alphabetically when grades tie
data = [('Alice', 85), ('Bob', 92), ('Charlie', 85), ('Dave', 78)]
result = sorted(data, key=lambda x: (x[1], x[0]))
print(result)
# [('Dave', 78), ('Alice', 85), ('Charlie', 85), ('Bob', 92)]Alice e Charlie hanno entrambi voto 85, quindi vengono ordinati alfabeticamente — Alice prima di Charlie.
Stabilità dell'Ordinamento
L'ordinamento di Python è stabile: gli elementi che risultano uguali mantengono il loro ordine relativo originale. Ciò significa che puoi ordinare una lista per una chiave, poi ordinare il risultato per un'altra chiave, e l'ordine del primo ordinamento viene preservato nei pareggi della seconda chiave.
# Sort by grade, then (stably) by name — same result as the tuple key above
data = [('Alice', 85), ('Bob', 92), ('Charlie', 85), ('Dave', 78)]
step1 = sorted(data, key=lambda x: x[0]) # sort by name first
step2 = sorted(step1, key=lambda x: x[1]) # then sort by grade
print(step2)
# [('Dave', 78), ('Alice', 85), ('Charlie', 85), ('Bob', 92)]Questa tecnica — chiamata trasformata di Schwartzian — è talvolta più leggibile di una chiave composita.
Conclusione
sorted() e list.sort() di Python offrono un ordinamento delle liste veloce e flessibile con il minimo del codice. Usa sorted() quando hai bisogno di una nuova lista o stai ordinando un iterabile non-lista; usa list.sort() quando vuoi modificare una lista in-place. Il parametro key gestisce quasi qualsiasi criterio di ordinamento — dall'ordinamento per lunghezza o un campo di un dizionario ai confronti senza distinzione tra maiuscole e minuscole. Per grandi set di dati, preferisci operator.itemgetter o operator.attrgetter rispetto alle lambda per ottenere prestazioni migliori.
Letture correlate:
- Python Lists — creazione, indicizzazione e slicing delle liste
- List Methods — riferimento completo per i metodi delle liste
- List Comprehension — costruzione concisa di liste
- Loop Lists — iterazione sulle liste