Question Comment comparer une liste de listes / ensembles en python?


Quelle est la manière la plus simple de comparer les 2 listes / ensembles et de générer les différences? Existe-t-il des fonctions intégrées qui vont m'aider à comparer des listes / ensembles imbriqués?

Contributions:

First_list = [['Test.doc', '1a1a1a', 1111], 
              ['Test2.doc', '2b2b2b', 2222],  
              ['Test3.doc', '3c3c3c', 3333]
             ]  
Secnd_list = [['Test.doc', '1a1a1a', 1111], 
              ['Test2.doc', '2b2b2b', 2222], 
              ['Test3.doc', '8p8p8p', 9999], 
              ['Test4.doc', '4d4d4d', 4444]]  

Production attendue:

Differences = [['Test3.doc', '3c3c3c', 3333],
               ['Test3.doc', '8p8p8p', 9999], 
               ['Test4.doc', '4d4d4d', 4444]]

22
2018-05-24 04:46


origine


Réponses:


Donc, vous voulez la différence entre deux listes d'éléments.

first_list = [['Test.doc', '1a1a1a', 1111], 
              ['Test2.doc', '2b2b2b', 2222], 
              ['Test3.doc', '3c3c3c', 3333]]
secnd_list = [['Test.doc', '1a1a1a', 1111], 
              ['Test2.doc', '2b2b2b', 2222], 
              ['Test3.doc', '8p8p8p', 9999], 
              ['Test4.doc', '4d4d4d', 4444]]

D'abord, je vais transformer chaque liste de listes en une liste de tuples, de sorte que les tuples soient lavables (les listes ne le sont pas) afin que vous puissiez convertir votre liste de tuples en un ensemble de tuples:

first_tuple_list = [tuple(lst) for lst in first_list]
secnd_tuple_list = [tuple(lst) for lst in secnd_list]

Ensuite, vous pouvez faire des sets:

first_set = set(first_tuple_list)
secnd_set = set(secnd_tuple_list)

EDIT (suggéré par sdolan): Vous auriez pu faire les deux dernières étapes pour chaque liste dans une liste unique:

first_set = set(map(tuple, first_list))
secnd_set = set(map(tuple, secnd_list))

Remarque: map est une commande de programmation fonctionnelle qui applique la fonction dans le premier argument (dans ce cas, la tuple fonction) à chaque élément du second argument (qui dans notre cas est une liste de listes).

et trouver la différence symétrique entre les ensembles:

>>> first_set.symmetric_difference(secnd_set) 
set([('Test3.doc', '3c3c3c', 3333),
     ('Test3.doc', '8p8p8p', 9999),
     ('Test4.doc', '4d4d4d', 4444)])

Remarque first_set ^ secnd_set est équivalent à symmetric_difference.

Aussi, si vous ne voulez pas utiliser d'ensembles (par exemple, en utilisant python 2.2), c'est assez simple à faire. Par exemple, avec des compréhensions de liste:

>>> [x for x in first_list if x not in secnd_list] + [x for x in secnd_list if x not in first_list]
[['Test3.doc', '3c3c3c', 3333],
 ['Test3.doc', '8p8p8p', 9999],
 ['Test4.doc', '4d4d4d', 4444]]

ou avec le fonctionnel filter commande et lambda les fonctions. (Vous devez tester les deux manières et combiner).

>>> filter(lambda x: x not in secnd_list, first_list) + filter(lambda x: x not in first_list, secnd_list)

[['Test3.doc', '3c3c3c', 3333],
 ['Test3.doc', '8p8p8p', 9999],
 ['Test4.doc', '4d4d4d', 4444]]

29
2018-05-24 04:54



Je ne suis pas sûr qu’il y ait une bonne fonction pour cela, mais la manière "manuelle" de le faire n’est pas difficile:

differences = []

for list in firstList:
    if list not in secondList:
        differences.append(list)

3
2018-05-24 04:58



>>> First_list = [['Test.doc', '1a1a1a', '1111'], ['Test2.doc', '2b2b2b', '2222'], ['Test3.doc', '3c3c3c', '3333']] 
>>> Secnd_list = [['Test.doc', '1a1a1a', '1111'], ['Test2.doc', '2b2b2b', '2222'], ['Test3.doc', '3c3c3c', '3333'], ['Test4.doc', '4d4d4d', '4444']] 


>>> z = [tuple(y) for y in First_list]
>>> z
[('Test.doc', '1a1a1a', '1111'), ('Test2.doc', '2b2b2b', '2222'), ('Test3.doc', '3c3c3c', '3333')]
>>> x = [tuple(y) for y in Secnd_list]
>>> x
[('Test.doc', '1a1a1a', '1111'), ('Test2.doc', '2b2b2b', '2222'), ('Test3.doc', '3c3c3c', '3333'), ('Test4.doc', '4d4d4d', '4444')]


>>> set(x) - set(z)
set([('Test4.doc', '4d4d4d', '4444')])

2
2018-05-24 05:00



Je suppose que vous devrez convertir vos listes en ensembles:

>>> a = {('a', 'b'), ('c', 'd'), ('e', 'f')}
>>> b = {('a', 'b'), ('h', 'g')}
>>> a.symmetric_difference(b)
{('e', 'f'), ('h', 'g'), ('c', 'd')}

1
2018-05-24 04:57



http://docs.python.org/library/difflib.html est un bon point de départ pour ce que vous recherchez.

Si vous l'appliquez récursivement aux deltas, vous devriez être capable de gérer les structures de données imbriquées. Mais il faudra du travail.


0
2018-05-24 04:53



En utilisant des compréhensions d'ensemble, vous pouvez en faire un one-liner. Si tu veux:

pour obtenir un ensemble de tuples, alors:

Differences = {tuple(i) for i in First_list} ^ {tuple(i) for i in Secnd_list}

Ou pour obtenir une liste de tuples, alors:

Differences = list({tuple(i) for i in First_list} ^ {tuple(i) for i in Secnd_list})

Ou pour obtenir une liste de listes (si vous voulez vraiment), alors:

Differences = [list(j) for j in {tuple(i) for i in First_list} ^ {tuple(i) for i in Secnd_list}]

PS: j'ai lu ici: https://stackoverflow.com/a/10973817/4900095 cette fonction map () n'est pas une façon pythonique de faire les choses.


0
2017-09-29 08:08