Cet article décrit comment générer une nouvelle liste en Python en supprimant et en extrayant les éléments en double d’une liste. Notez que la suppression des éléments en double équivaut à extraire uniquement les éléments uniques.
La même idée peut être appliquée aux tuples plutôt qu’aux listes.
Pour vérifier si une liste ou un tuple contient des éléments en double, ou pour extraire des éléments communs ou non communs à plusieurs listes, consultez les articles suivants.
- Vérifier si une liste contient des doubles en Python
- Extraire des éléments communs/non communs/uniques de plusieurs listes en Python
Supprimer les éléments en double (extraire les éléments uniques) d’une liste
Ne conservez pas l’ordre de la liste d’origine : 𝐬𝐞𝐭()
Utilisez 𝐬𝐞𝐭() si vous n’avez pas besoin de conserver l’ordre de la liste d’origine.
En passant une liste à 𝐬𝐞𝐭() , il renvoie 𝐬𝐞𝐭 , qui ignore les valeurs en double et conserve uniquement les valeurs uniques comme éléments.
𝐬𝐞𝐭 peut être reconverti en liste ou en tuple avec 𝐥𝐢𝐬𝐭() ou 𝐭𝐮𝐩𝐥𝐞() .
l = [3, 3, 2, 1, 5, 1, 4, 2, 3] print(set(l)) # {1, 2, 3, 4, 5} print(list(set(l))) # [1, 2, 3, 4, 5]
Bien sûr, vous pouvez utiliser 𝐬𝐞𝐭 tel quel. Consultez l’article suivant pour plus d’informations sur 𝐬𝐞𝐭 .
Conservez l’ordre de la liste d’origine : 𝐝𝐢𝐜𝐭.𝐟𝐫𝐨𝐦𝐤𝐞𝐲𝐬() , 𝐬𝐨𝐫𝐭𝐞𝐝()
Si vous souhaitez conserver l’ordre de la liste d’origine, utilisez 𝐝𝐢𝐜𝐭.𝐟𝐫𝐨𝐦𝐤𝐞𝐲𝐬() ou 𝐬𝐨𝐫𝐭𝐞𝐝() .
𝐝𝐢𝐜𝐭.𝐟𝐫𝐨𝐦𝐤𝐞𝐲𝐬() crée un nouveau dictionnaire avec les clés de l’itérable. Si le deuxième argument est omis, la valeur par défaut est définie sur N𝐨𝐧𝐞 .
Étant donné qu’une clé de dictionnaire ne peut pas contenir d’éléments en double, les valeurs en double sont ignorées comme 𝐬𝐞𝐭() . Passer un dictionnaire à 𝐥𝐢𝐬𝐭() renvoie une liste avec des clés de dictionnaire comme éléments.
l = [3, 3, 2, 1, 5, 1, 4, 2, 3] print(dict.fromkeys(l)) # {3: None, 2: None, 1: None, 5: None, 4: None} print(list(dict.fromkeys(l))) # [3, 2, 1, 5, 4]
À partir de Python 3.7 (3.6 pour CPython), 𝐝𝐢𝐜𝐭.𝐟𝐫𝐨𝐦𝐤𝐞𝐲𝐬() garantit que l’ordre de séquence est préservé. Dans les versions antérieures, vous pouvez utiliser la fonction intégrée 𝐬𝐨𝐫𝐭𝐞𝐝() comme décrit ci-dessous.
La méthode 𝐢𝐧𝐝𝐞𝐱() renvoie l’index d’une valeur. En le spécifiant comme paramètre 𝐤𝐞𝐲 dans 𝐬𝐨𝐫𝐭𝐞𝐝() , la liste peut être triée en fonction de l’ordre de la liste d’origine.
print(sorted(set(l), key=l.index)) # [3, 2, 1, 5, 4]
Pour une liste bidimensionnelle
Pour une liste bidimensionnelle (liste de listes), l’utilisation de 𝐬𝐞𝐭() ou 𝐝𝐢𝐜𝐭.𝐟𝐫𝐨𝐦𝐤𝐞𝐲𝐬() générera un T𝐲𝐩𝐞E𝐫𝐫𝐨𝐫 .
l_2d = [[1, 1], [0, 1], [0, 1], [0, 0], [1, 0], [1, 1], [1, 1]] # l_2d_unique = list(set(l_2d)) # TypeError: unhashable type: 'list' # l_2d_unique_order = dict.fromkeys(l_2d) # TypeError: unhashable type: 'list'
Cela est dû au fait que les objets non hachables tels que les listes ne peuvent pas être des éléments de type 𝐬𝐞𝐭 ou des clés de type 𝐝𝐢𝐜𝐭 .
Définissez la fonction suivante pour résoudre ce problème. Cette fonction préserve l’ordre de la liste d’origine et fonctionne à la fois pour les listes unidimensionnelles et les tuples.
def get_unique_list(seq): seen = [] return [x for x in seq if x not in seen and not seen.append(x)] print(get_unique_list(l_2d)) # [[1, 1], [0, 1], [0, 0], [1, 0]] print(get_unique_list(l)) # [3, 2, 1, 5, 4]
La compréhension de liste est utilisée.
Extraire les éléments en double d’une liste
Ne pas conserver l’ordre de la liste d’origine
Si vous souhaitez extraire uniquement les éléments en double de la liste d’origine, utilisez 𝐜𝐨𝐥𝐥𝐞𝐜𝐭𝐢𝐨𝐧 𝐬.C𝐨𝐮𝐧𝐭𝐞𝐫() retourner ici 𝐜𝐨𝐥𝐥𝐞𝐜𝐭𝐢𝐨 𝐧𝐬.C𝐨𝐮𝐧𝐭𝐞𝐫 (sous-classe de dictionnaire) dont la clé est un élément et dont la valeur est son nombre.
import collections l = [3, 3, 2, 1, 5, 1, 4, 2, 3] print(collections.Counter(l)) # Counter({3: 3, 2: 2, 1: 2, 5: 1, 4: 1})
Comme il s’agit d’une sous-classe d’un dictionnaire, vous pouvez récupérer des clés et des valeurs avec 𝐢𝐭𝐞𝐦𝐬() . Vous pouvez extraire des clés avec plus de deux comptes par compréhension de liste.
print([k for k, v in collections.Counter(l).items() if v > 1]) # [3, 2, 1]
Conserver l’ordre de la liste d’origine
Comme dans l’exemple ci-dessus, depuis Python 3.7, la clé de 𝐜𝐨𝐥𝐥𝐞𝐜𝐭𝐢𝐨 𝐧𝐬.C𝐨𝐮𝐧𝐭𝐞𝐫 préserver l’ordre de la liste d’origine.
Dans les versions antérieures, vous pouvez trier par 𝐬𝐨𝐫𝐭𝐞𝐝() comme dans l’exemple pour supprimer les éléments en double.
l = [3, 3, 2, 1, 5, 1, 4, 2, 3] print(sorted([k for k, v in collections.Counter(l).items() if v > 1], key=l.index)) # [3, 2, 1]
Si vous souhaitez extraire des éléments dans leur état dupliqué, incluez simplement les éléments avec deux occurrences ou plus de la liste d’origine. L’ordre est également conservé.
cc = collections.Counter(l) print([x for x in l if cc[x] > 1]) # [3, 3, 2, 1, 1, 2, 3]
Pour une liste bidimensionnelle
Pour une liste bidimensionnelle (liste de listes) :
l_2d = [[1, 1], [0, 1], [0, 1], [0, 0], [1, 0], [1, 1], [1, 1]] def get_duplicate_list(seq): seen = [] return [x for x in seq if not seen.append(x) and seen.count(x) == 2] def get_duplicate_list_order(seq): seen = [] return [x for x in seq if seq.count(x) > 1 and not seen.append(x) and seen.count(x) == 1] print(get_duplicate_list(l_2d)) # [[0, 1], [1, 1]] print(get_duplicate_list_order(l_2d)) # [[1, 1], [0, 1]] print(get_duplicate_list(l)) # [3, 1, 2] print(get_duplicate_list_order(l)) # [3, 2, 1]
print([x for x in l_2d if l_2d.count(x) > 1]) # [[1, 1], [0, 1], [0, 1], [1, 1], [1, 1]]
Notez que 𝐜𝐨𝐮𝐧𝐭() nécessite O(𝐧) , donc la fonction qui exécute de manière répétée 𝐜𝐨𝐮𝐧𝐭() illustrée ci-dessus est très inefficace. Il existe peut-être des approches plus efficaces et optimisées.
Étant donné que 𝐜𝐨𝐥𝐥𝐞𝐜𝐭𝐢𝐨 𝐧𝐬.C𝐨𝐮𝐧𝐭𝐞𝐫 est une sous-classe du dictionnaire, une erreur est générée si vous passez une liste ou un tuple dont les éléments ne sont pas hachables, comme une liste, à 𝐜𝐨𝐥𝐥𝐞𝐜𝐭𝐢𝐨𝐧𝐬.C𝐨𝐮𝐧𝐭𝐞𝐫() .
# print(collections.Counter(l_2d)) # TypeError: unhashable type: 'list'