290 votes

Opération de soustraction de liste en Python

Je veux faire quelque chose de similaire :

>>> x = [1,2,3,4,5,6,7,8,9,0]  
>>> x  
[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]  
>>> y = [1,3,5,7,9]  
>>> y  
[1, 3, 5, 7, 9]  
>>> y - x   # (should return [2,4,6,8,0])

Mais ceci n'est pas supporté par les listes python. Quelle est la meilleure façon de procéder ?

0 votes

@ezdazuzena ce n'est pas une soustraction. C'est la différence entre deux listes. Votre partage n'est pas une dublication de cette question.

2 votes

Que doit donner [2, 2] - [2] ? [] ? [2] ?

0 votes

@McKay [2,2] - [2] devrait donner [2]. [2,2] - [1,2,2,3] devrait donner [].

413voto

aaronasterling Points 25749

Utilisez une liste de compréhension :

[item for item in x if item not in y]

Si vous voulez utiliser le - syntaxe infixe, vous pouvez simplement faire :

class MyList(list):
    def __init__(self, *args):
        super(MyList, self).__init__(args)

    def __sub__(self, other):
        return self.__class__(*[item for item in self if item not in other])

vous pouvez alors l'utiliser comme :

x = MyList(1, 2, 3, 4)
y = MyList(2, 5, 2)
z = x - y   

Mais si vous n'avez pas absolument besoin des propriétés des listes (par exemple, l'ordre), utilisez simplement les ensembles comme le recommandent les autres réponses.

11 votes

@admica, n'utilisez pas list pour les noms de variables car elle fait de l'ombre à la list constructeur. Si vous utilisez 'list', veuillez le faire précéder d'un trait de soulignement. De plus, en supprimant l'élément * tu as cassé mon code...

29 votes

Si vous le faites [1,1,2,2] - [1,2] vous obtiendrez une liste vide. [1,1,2,2] - [2] donne [1,1] Donc ce n'est pas vraiment une soustraction de liste, c'est plus comme "Liste de la liste X sans éléments de l'ensemble Y " .

0 votes

@AlfredZien ce qu'il a dit

319voto

quantumSoup Points 6565

Utilisez différence définie

>>> z = list(set(x) - set(y))
>>> z
[0, 8, 2, 4, 6]

Ou vous pouvez simplement faire en sorte que x et y soient des ensembles pour ne pas avoir à effectuer de conversions.

72 votes

Cela perdra toute commande. Cela peut être important ou non selon le contexte.

77 votes

Cela permettra également de perdre les éventuels doublons qui doivent/doivent être entretenus.

1 votes

Je reçois TypeError: unhashable type: 'dict'

41voto

Santa Points 6013

Il s'agit d'une opération de "soustraction d'ensemble". Utilisez la structure de données set pour cela.

Dans Python 2.7 :

x = {1,2,3,4,5,6,7,8,9,0}
y = {1,3,5,7,9}
print x - y

Sortie :

>>> print x - y
set([0, 8, 2, 4, 6])

1 votes

List(set([1,2,3,4,5]) - set([1,2,3])) = [4, 5] donc chaque liste est d'abord transformée en set, puis en soustraction (ou en différence à sens unique) et en liste.

3 votes

Ce n'est pas bon si vous voulez conserver l'ordre original des éléments de l'ensemble x.

41voto

nguyên Points 551

Si les doublons et les articles de commande posent problème :

[i for i in a if not i in b or b.remove(i)]

a = [1,2,3,3,3,3,4]
b = [1,3]
result: [2, 3, 3, 3, 4]

2 votes

Cela fonctionne, mais c'est O(m * n) (et je craque à chaque fois qu'une compilation de liste inclut des effets secondaires) ; vous pouvez l'améliorer en utilisant collections.Counter pour obtenir O(m + n) temps d'exécution.

0 votes

J'ai du mal à comprendre, quelqu'un peut-il m'expliquer ?

2voto

user3435376 Points 11

Essayez ça.

def subtract_lists(a, b):
    """ Subtracts two lists. Throws ValueError if b contains items not in a """
    # Terminate if b is empty, otherwise remove b[0] from a and recurse
    return a if len(b) == 0 else [a[:i] + subtract_lists(a[i+1:], b[1:]) 
                                  for i in [a.index(b[0])]][0]

>>> x = [1,2,3,4,5,6,7,8,9,0]
>>> y = [1,3,5,7,9]
>>> subtract_lists(x,y)
[2, 4, 6, 8, 0]
>>> x = [1,2,3,4,5,6,7,8,9,0,9]
>>> subtract_lists(x,y)
[2, 4, 6, 8, 0, 9]     #9 is only deleted once
>>>

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