Je travaille sur un code qui supprime les éléments en double d'une liste. L'ordre des doublons peut être différent, mais je considérerais toujours les deux comme les mêmes.

Par exemple, je considérerais [[m, b], [c, d]] et [[c, d], [m, b]] comme des doublons.

Je travaille sur un code qui reconnaîtrait ces doublons et supprimerait le supplément de la liste globale. Jusqu'à présent, je l'ai essayé sur une liste sans aucun doublon, donc la liste de fin devrait rester inchangée.

Voici la liste,

A= [[[a1, b1], [a1, b1]],
 [[a2, b2], [a2, b2]],
 [[a3, b3], [a3, b3]],
 [[a4, b4], [a4, b4]]]

Le code que j'utilise est,

for i in A:
    for j in A:
        if j[1]== i[0]:
            if j[0]==i[1]:
                A.remove(j)

Je veux que le code compare le deuxième élément dans la liste interne donnée (j [1]) avec le premier élément dans l'une des autres listes internes (i [0]) et similaire pour j [0] et i [1], et s'ils sont égaux (c'est-à-dire que i et j sont des doublons l'un de l'autre), alors l'un des éléments est supprimé de la liste.

Le problème est qu'avec ce code, la sortie n'aurait pas dû être différente de la liste de départ (A), mais le résultat était le suivant,

[[[a2, b2], [a2, b2]], [[a4, b4], [a4, b4]]]

Je cherche simplement à expliquer pourquoi cela a pu arriver et comment modifier mon code pour éviter le problème.

0
Asiv 4 juin 2020 à 22:13

3 réponses

Meilleure réponse

Je pense que je l'ai:

B = A.copy()
C = A.copy()
for index, element in enumerate(B):
    try:
        if set(B[index][0]) == set(C[index + 1][0]) or set(B[index][1]) == set(C[index + 1][1]):
            A.remove(element)
    except:
        pass

Dans le cas de

A = [
    [['a1', 'b1'], ['a1', 'b1']],
    [['a2', 'b2'], ['b2', 'a2']],
    [['a3', 'b3'], ['a3', 'b3']],
    [['a4', 'b4'], ['a4', 'b4']]
]

Cela renvoie A

Alors que si vous avez:

A = [
    [['a1', 'b1'], ['a1', 'b1']],
    [['a1', 'b1'], ['b1', 'a1']],
    [['a3', 'b3'], ['a3', 'b3']],
    [['a4', 'b4'], ['a4', 'b4']]
]

Il renvoie:

A = [
    [['a1', 'b1'], ['b1', 'a1']],
    [['a3', 'b3'], ['a3', 'b3']],
    [['a4', 'b4'], ['a4', 'b4']]
]

Dans votre code, cela n'a pas fonctionné car vous supprimiez des éléments de ce que vous répétiez. De plus, vérifier si les listes sont égales les unes aux autres ne vous dira pas si elles contiennent les mêmes éléments, c'est-à-dire que [a,b] == [b,a] renvoie False. Vous devrez plutôt comparer des ensembles.

J'espère que cela t'aides.

1
Jacob Strauss 4 juin 2020 à 21:12

Pour comparer l'intersection de deux listes, il peut être utile d'utiliser des ensembles , surtout si vos listes comportent plus de deux éléments.

a = ['m', 'n']
b = ['n', 'o']
print(set(a) & set(b)) # The & operator returns the intersecting elements

-> {'n'}

Quant à votre question, ce code devrait fonctionner:

for a in A:
  B = A.copy()
  B.remove(a) # so you don't compare a to a and mark it as a duplicate
  for b in B:
    if set(b[0]) & set(b[1]):
      A.remove(b)
2
Zciurus-Alt-Del 4 juin 2020 à 19:40

Essaye ça:

>>> import numpy as np
>>> def remove_duplicates(A):
...     for sublist in A:
...             sublist.sort()
...     B = []
...     for sublist in A:
...             if sublist not in B:
...                     B.append(sublist)
...     return B
... 
>>> A = np.random.randint(low=0, high=3, size=(8, 2)).tolist()
>>> A
[[0, 1], [1, 0], [0, 2], [0, 0], [2, 2], [2, 2], [0, 2], [1, 0]]
>>> remove_duplicates(A)
[[0, 1], [0, 2], [0, 0], [2, 2]]

Testé sur python 3.7.7.

1
G Oliveira 4 juin 2020 à 19:45