2017-10-12 7 views
2

J'ai deux tuples a = ((1, 'AB'), (2, 'BC'), (3, 'CD')) et b = ((1, 'AB'), (2, 'XY'), (3, 'ZA')). En analysant ces deux tuples, on peut trouver qu'il y a des mésappariements dans les tuples, par exemple, (2, 'BC') est présent dans a mais (2, 'XY') est présent dans b.Trouver des discordances dans les tuples et les fusionner en Python

J'ai besoin de comprendre ces discordances et venir avec un tuple qui a les valeurs que

result = ((2, 'BC', 'XY'), (3, 'CD', 'ZA')) 

(ordre est conservé)

La référence la plus proche que je pouvais attraper est Comparing sublists and merging them, mais est pour les listes et je ne pouvais pas trouver un moyen de travailler avec des tuples.

Existe-t-il un moyen par lequel je peux effectuer cette opération?

+2

Où est votre code jusqu'à présent? Où avez-vous été bloqué spécifiquement? – smarx

+0

@ Jean-FrançoisFabre Peut ignorer ce cas. Seulement s'il y a une discordance, le résultat devrait avoir l'article dans le tuple. –

Répondre

5

Comme il ne peut pas manquer « clés » de a ou b (ou ces valeurs doivent être ignorées), je me tournerais b dans un dictionnaire, puis boucle sur a et comparer les valeurs.

a = ((1, 'AB'), (2, 'BC'), (3, 'CD')) 
b = ((1, 'AB'), (2, 'XY'), (3, 'ZA')) 

b = dict(b) 

mismatches = [(k,v,b[k]) for k,v in a if b.get(k,v) != v] 

print(mismatches) 

Résultat:

[(2, 'BC', 'XY'), (3, 'CD', 'ZA')] 

la solution a l'avantage d'être près de 1 ligne, rapide (à cause de dict recherche) et préserve l'ordre.

les garanties condition if b.get(k,v) != v contre a ayant un tuple avec un numéro non dans b dictionnaire. Dans ce cas, la valeur par défaut de get retours v et la condition est False

+0

On dirait que cela fonctionne, même si nous faisons 'b.get (k)' au lieu de 'b.get (k, v)' dans la ligne 'mismatches' –

+1

ne passant pas la valeur par défaut de' a' signifie que vous ' ll obtiendra une erreur de clé quand 'a' a une clé supplémentaire. Essayez-le. –

0

Si les listes sont garantis d'avoir le même ordre des numéros dans les tuples, vous pouvez faire quelque chose comme:

[ai + (bi[1],) for ai, bi in zip(a, b) if ai != bi] 

et s'il n'y a aucune garantie sur l'ordre que vous pouvez faire:

[ai + (bi[1],) for ai, bi in zip(sorted(a), sorted(b)) if ai != bi]