Quel est le moyen le plus simple de comparer les 2 listes/ensembles et d’en extraire les différences? Existe-t-il des fonctions intégrées qui m'aideront à comparer les 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]]
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]]
Premièrement, je transformerais chaque liste de listes en une liste de n-uplets, afin que les n-uplets puissent être remplis (les listes ne le soient pas) afin que vous puissiez convertir votre liste de n-uplets en un ensemble de n-uplets:
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 ensembles:
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 en une ligne:
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 fonction Tuple
) à chaque élément du deuxième argument (qui dans notre cas est une liste de listes).
et trouvez 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
.
De plus, si vous ne voulez pas utiliser d'ensembles (par exemple, en utilisant python 2.2), sa tâche est simple. 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 la commande fonctionnelle filter
et les fonctions lambda
. (Vous devez tester les deux méthodes 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]]
Je ne sais pas s'il existe une fonction Nice pour cela, mais la façon "manuelle" de le faire n'est pas difficile:
differences = []
for list in firstList:
if list not in secondList:
differences.append(list)
>>> 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')])
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')}
En utilisant des ensembles, vous pouvez en faire un one-line. Si tu veux:
pour obtenir un jeu 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: Je lis ici: https://stackoverflow.com/a/10973817/4900095 cette fonction map () n’est pas une façon pythonique de faire les choses.
Ancienne question, mais voici une solution que j'utilise pour renvoyer des éléments uniques qui ne figurent pas dans les deux listes.
J'utilise ceci pour comparer les valeurs renvoyées par une base de données et les valeurs générées par un package d'indexeur de répertoires. Je n'ai pas aimé les autres solutions que j'ai trouvées car beaucoup d'entre elles ne pouvaient pas gérer de manière dynamique les listes non hiérarchiques et les listes imbriquées.
def differentiate(x, y):
"""
Retrieve a unique of list of elements that do not exist in both x and y.
Capable of parsing one-dimensional (flat) and two-dimensional (lists of lists) lists.
:param x: list #1
:param y: list #2
:return: list of unique values
"""
# Validate both lists, confirm either are empty
if len(x) == 0 and len(y) > 0:
return y # All y values are unique if x is empty
Elif len(y) == 0 and len(x) > 0:
return x # All x values are unique if y is empty
# Get the input type to convert back to before return
try:
input_type = type(x[0])
except IndexError:
input_type = type(y[0])
# Dealing with a 2D dataset (list of lists)
try:
# Immutable and Unique - Convert list of tuples into set of tuples
first_set = set(map(Tuple, x))
secnd_set = set(map(Tuple, y))
# Dealing with a 1D dataset (list of items)
except TypeError:
# Unique values only
first_set = set(x)
secnd_set = set(y)
# Determine which list is longest
longest = first_set if len(first_set) > len(secnd_set) else secnd_set
shortest = secnd_set if len(first_set) > len(secnd_set) else first_set
# Generate set of non-shared values and return list of values in original type
return [input_type(i) for i in {i for i in longest if i not in shortest}]
http://docs.python.org/library/difflib.html est un bon point de départ pour ce que vous recherchez.
Si vous l'appliquez de manière récursive aux deltas, vous devriez être capable de gérer des structures de données imbriquées. Mais cela prendra du travail.