0
votes

Comment supprimer les doublons d'une liste d'objets personnalisés en Python à l'aide d'une fonction d'égalité personnalisée?

Comment puis-je supprimer succinctement les doublons d'une list d'objets personnalisés à l'aide d'une fonction d'égalité personnalisée?

De nombreuses solutions repose sur set() ou le haut- in l' opérateur, mais je ne peux pas garantir que les objets ont défini __eq__ ou __hash__ .

Une solution peut-elle être écrite plus succinctement en utilisant des listes de compréhension ou d'autres astuces astucieuses que ma tentative initiale?

l = [4, 9, 5, 1, 3, 1, 8, 9, 5, 4]
result = [] 

for n,i in enumerate(l):
    found=False
    for j in l[:n]:
        if (lambda a, b: a == b)(i,j): // or use a custom function
            found=True
            break
    if not found:
        result.append(i)

print(l)
print(result)


2 commentaires

stackoverflow.com/questions/30310542/...


"Je ne peux pas garantir que les objets ont défini __eq__ ou __hash__ ." - Ils auront les deux par défaut à moins qu'ils ne les définissent explicitement sur None . (Ou s'ils définissent explicitement __eq__ sans définir __hash__ , leur __hash__ sera implicitement None .)


3 Réponses :


2
votes
[v1 for i, v1 in enumerate(l) if not any(v1 == v2 for v2 in l[:i])]

4 commentaires

Comment any() prendre v1 == v2 for v2 in l[:i] comme argument? Si vous v1 == v2 for v2 in l[:i] autonome, vous obtenez une erreur de syntaxe. Quel est le mécanisme (fonction de langue) utilisé ici?


@Shuzheng Si vous avez une compréhension du générateur comme seul argument d'une fonction, vous êtes autorisé à omettre les parenthèses extérieures. Si vous trouvez cela déroutant, utilisez la première version, qui les inclut explicitement.


Je vois que j'ai besoin de parenthèses autour de v1 == v2 for v2 in l[:i] : (v1 == v2 for v2 in l[:i]) , pourquoi est-ce nécessaire? Et pourquoi peut-il être laissé de côté dans un appel de fonction?


@Shuzheng Je suppose que c'est juste une sténographie autorisée car il n'y a rien avec lequel elle pourrait être confondue.



1
votes
l = [4, 9, 5, 1, 3, 1, 8, 9, 5, 4]
result = [] 

for n,i in enumerate(l):
    if i not in result:
        result.append(i)
    else:
        continue
print(l)
print(result)

2 commentaires

Vous n'avez pas besoin du cas spécial n == 0 .


Je vais modifier ceci pour supprimer le cas spécial - j'espère que cela vous convient. Lorsque n == 0 (la première itération), le result est une liste vide et que i not in result évaluera de toute façon True .



0
votes

Hy, il n'est pas nécessaire d'utiliser enumerate:

l = [4, 9, 5, 1, 3, 1, 8, 9, 5, 4]
result = []

for i in l:
    if i not in result:
        result.append(i)
    else:
        continue
print(result)


0 commentaires