Rimuovere i duplicati in Python: Guida completa
Cinque modi pratici per rimuovere i duplicati da una lista Python: set, dict.fromkeys, ciclo for, list comprehension e Counter.
I valori duplicati in una lista Python sono comuni quando si raccolgono dati dagli utenti, si uniscono dataset o si leggono file. Questa guida illustra cinque tecniche pratiche per rimuovere i duplicati — ognuna con un compromesso diverso tra velocità, mantenimento dell'ordine e leggibilità.
| Metodo | Mantiene l'ordine | Funziona con elementi non hashable | Leggibile |
|---|---|---|---|
set() | No | No | Sì |
dict.fromkeys() | Sì (Python 3.7+) | No | Sì |
| Ciclo for con seen set | Sì | No | Medio |
| List comprehension | Sì | No | Medio |
Counter (trova i dup.) | Sì | No | Sì |
Usare set() per rimuovere i duplicati
Convertire una lista in un set è il modo più veloce e conciso per deduplicare. Un set memorizza solo valori unici e hashable, quindi i duplicati vengono scartati automaticamente.
Output (l'ordine può variare):
[1, 2, 3, 4, 5]Quando usarlo: l'ordine non è importante e la lista contiene solo elementi hashable (numeri, stringhe, tuple).
Attenzione: i set non sono ordinati. Anche se i set di interi piccoli spesso vengono stampati in ordine, non è garantito. Se l'ordine è importante, usa uno dei metodi seguenti.
Usare dict.fromkeys() per preservare l'ordine
dict.fromkeys() crea un dizionario le cui chiavi sono gli elementi della lista. Poiché le chiavi di un dizionario sono uniche e, a partire da Python 3.7, mantengono l'ordine di inserimento, questo metodo rimuove i duplicati preservando l'ordine originale.
Output:
[1, 2, 3, 4, 5]Questo è il one-liner idiomatico per la deduplicazione con preservazione dell'ordine in Python moderno (3.7+). È anche leggermente più veloce di un ciclo esplicito perché le operazioni sul dizionario avvengono in C.
Usare un ciclo for con un seen set
Quando si desidera il controllo completo — ad esempio per registrare i duplicati saltati o applicare logica di uguaglianza personalizzata — un ciclo esplicito è l'approccio più chiaro.
def remove_duplicates(lst):
seen = set()
result = []
for item in lst:
if item not in seen:
seen.add(item)
result.append(item)
return result
my_list = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]
print(remove_duplicates(my_list))Output:
[3, 1, 4, 5, 9, 2, 6]Questo preserva l'ordine di inserimento e viene eseguito in tempo O(n) — il controllo in su un set è O(1). Confrontalo con if item not in result, che è O(n) per elemento e rende l'intera funzione O(n²).
Usare la list comprehension
È possibile scrivere lo stesso pattern con seen set come one-liner usando una list comprehension. Il trucco è che set.add() restituisce sempre None (falsy), quindi not (x in seen or seen.add(x)) è True solo la prima volta che ogni valore compare.
my_list = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3]
seen = set()
unique = [x for x in my_list if not (x in seen or seen.add(x))]
print(unique)Output:
[3, 1, 4, 5, 9, 2, 6]Questo è compatto ma si basa su un effetto collaterale all'interno della comprehension, che può sorprendere chi legge il codice. Il ciclo for esplicito è spesso preferito nel codice di squadra.
Usare Counter per trovare i valori duplicati
A volte è necessario sapere quali valori compaiono più di una volta, anziché semplicemente rimuoverli. collections.Counter conta le occorrenze e rende questo semplice.
from collections import Counter
my_list = [1, 2, 2, 3, 4, 4, 5, 5, 5]
counts = Counter(my_list)
print(counts)
duplicates = [item for item, count in counts.items() if count > 1]
print("Duplicated values:", duplicates)Output:
Counter({5: 3, 2: 2, 4: 2, 1: 1, 3: 1})
Duplicated values: [2, 4, 5]Per ottenere una lista deduplicata da un Counter, usa list(counts.keys()) — le chiavi mantengono l'ordine di inserimento in Python 3.7+.
Rimuovere i duplicati da un DataFrame con Pandas
Se stai lavorando con dati tabulari, la libreria Pandas mette a disposizione DataFrame.drop_duplicates(). Supporta un controllo dettagliato tramite i suoi parametri.
import pandas as pd
data = {
'name': ['Alice', 'Bob', 'Alice', 'Charlie', 'Bob'],
'score': [90, 85, 90, 78, 85],
}
df = pd.DataFrame(data)
df_unique = df.drop_duplicates()
print(df_unique)Output:
name score
0 Alice 90
1 Bob 85
3 Charlie 78Parametri principali:
subset— un nome di colonna o una lista di nomi di colonne da considerare. I duplicati vengono rilevati solo all'interno di quelle colonne.keep—'first'(predefinito) mantiene la prima occorrenza;'last'mantiene l'ultima;Falseelimina tutte le righe con duplicati.inplace=True— modifica il DataFrame sul posto invece di restituirne uno nuovo.
# Keep only the last occurrence of each name
df_last = df.drop_duplicates(subset='name', keep='last')
print(df_last)Output:
name score
2 Alice 90
3 Charlie 78
4 Bob 85Scegliere il metodo giusto
- Più veloce, l'ordine non importa —
set(). - L'ordine è importante, one-liner —
dict.fromkeys(). - Logica personalizzata o logging — ciclo for esplicito con un seen set.
- Dati tabulari —
pandas.DataFrame.drop_duplicates(). - Occorre sapere quali valori sono duplicati —
collections.Counter.
Per ulteriori informazioni sull'utilizzo delle liste, consulta il capitolo Python Lists e il riferimento completo ai metodi delle liste. Per conoscere i set e le loro operazioni, vedi Python Sets e Set Methods.