235 votes

Calculer la différence de liste

En Python, quelle est la meilleure façon de calculer la différence entre deux listes ?

exemple

A = [1,2,3,4]
B = [2,5]

A - B = [1,3,4]
B - A = [5]

429voto

phihag Points 89765

Si l'ordre n'a pas d'importance vous pouvez simplement calculer la différence de réglage :

>>> set([1,2,3,4]) - set([2,5])
set([1, 4, 3])
>>> set([2,5]) - set([1,2,3,4])
set([5])

12 votes

C'est de loin la meilleure solution. Un test sur des listes contenant ~6000 chaînes de caractères chacune a montré que cette méthode était presque 100x plus rapide que les compréhensions de listes.

17 votes

Cela dépend de l'application : si la préservation de l'ordre ou de la duplication est importante, Roman Bodnarchuk peut avoir une meilleure approche. Pour la rapidité et le comportement pur des ensembles, celle-ci semble meilleure.

12 votes

Si vous avez plusieurs éléments égaux dans la liste, cette solution ne fonctionnera pas.

214voto

Roman Bodnarchuk Points 12136

Utilisez set si vous ne vous souciez pas de l'ordre des articles ou de leur répétition. Utilisez compréhensions de listes si vous le faites :

>>> def diff(first, second):
        second = set(second)
        return [item for item in first if item not in second]

>>> diff(A, B)
[1, 3, 4]
>>> diff(B, A)
[5]
>>>

34 votes

Envisagez d'utiliser set(b) pour que l'algorithme soit O(nlogn) au lieu de Thêta(n^2)

10 votes

@Pencilcheck - pas si vous vous souciez de l'ordre ou de la duplication dans l'application A. set à B est inoffensif, mais l'appliquer à A et utiliser le résultat au lieu de l'original A ne l'est pas.

1 votes

@NeilG Considérez-vous le temps consommé pour construire l'ensemble ? Dans mon cas (les deux listes ont environ 10 millions de chaînes), le temps nécessaire pour construire deux ensembles et les soustraire est considérablement plus important que celui nécessaire pour construire un ensemble et itérer sur la liste.

72voto

Senthil Kumaran Points 14934

Vous pouvez faire un

list(set(A)-set(B))

y

list(set(B)-set(A))

10 votes

Mais si A = [1,1,1] et B = [0], cela renvoie [1].

1 votes

@Mark Bell : C'est parce qu'un ensemble est une liste distincte. (supprime les doublons)

4 votes

@cloudy Alors cela ne répond pas à la question.

36voto

Artsiom Rudzenka Points 9771

Une doublure :

diff = lambda l1,l2: [x for x in l1 if x not in l2]
diff(A,B)
diff(B,A)

Ou :

diff = lambda l1,l2: filter(lambda x: x not in l2, l1)
diff(A,B)
diff(B,A)

8voto

The Communist Duck Points 2700

Il est préférable d'utiliser un set au lieu d'un list .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X