web-dev-qa-db-fra.com

python triant deux listes

J'essaie de trier deux listes ensemble:

list1 = [1, 2, 5, 4, 4, 3, 6]
list2 = [3, 2, 1, 2, 1, 7, 8]

list1, list2 = (list(x) for x in Zip(*sorted(Zip(list1, list2))))

Quoi qu’il en soit, cela me donne en sortie

list1 = [1, 2, 3, 4, 4, 5, 6]
list2 = [3, 2, 7, 1, 2, 1, 8]

alors que je voudrais garder l'ordre initial pour un nombre égal 4 dans la première liste: ce que je veux, c'est

list1 = [1, 2, 3, 4, 4, 5, 6]
list2 = [3, 2, 7, 2, 1, 1, 8]

Que dois-je faire? Je ne voudrais pas utiliser la boucle pour trier les bulles. Toute aide appréciée.

22
fmonegaglia

Utilisez un paramètre key pour votre tri qui compare uniquement le premier élément de la paire. Le tri de Python étant stable, cela garantit que l'ordre des deuxièmes éléments restera le même lorsque les premiers éléments sont égaux.

>>> from operator import itemgetter
>>> [list(x) for x in Zip(*sorted(Zip(list1, list2), key=itemgetter(0)))]
[[1, 2, 3, 4, 4, 5, 6], [3, 2, 7, 2, 1, 1, 8]]

Ce qui équivaut à:

>>> [list(x) for x in Zip(*sorted(Zip(list1, list2), key=lambda pair: pair[0]))]
[[1, 2, 3, 4, 4, 5, 6], [3, 2, 7, 2, 1, 1, 8]]
32
interjay

L'astuce ici est que lorsque Python effectue des comparaisons de tuples, il compare les éléments dans l'ordre, de gauche à droite (par exemple, (4, 1) < (4, 2), raison pour laquelle vous n'obtenez pas l'ordre souhaité dans votre cas particulier). Cela signifie que vous devez passer un argument key à la fonction sorted qui lui dit de n'utiliser que le premier élément de la paire Tuple en tant qu'expression de tri, plutôt que le Tuple entier.

Ceci est garanti pour conserver l'ordre que vous voulez parce que:

les tris sont garantis stables. Cela signifie que lorsque plusieurs enregistrements ont la même clé, leur ordre d'origine est conservé.

(la source)

>>> list1 = [1, 2, 5, 4, 4, 3, 6]
>>> list2 = [3, 2, 1, 2, 1, 7, 8]
>>> 
>>> list1, list2 = (list(x) for x in Zip(*sorted(Zip(list1, list2), key=lambda pair: pair[0])))
>>> 
>>> print list1
[1, 2, 3, 4, 4, 5, 6]
>>> print list2
[3, 2, 7, 2, 1, 1, 8]
5
Mark Amery

Dans votre code, le tri est effectué sur la base des premier et deuxième éléments des n-uplets, de sorte que les éléments de la deuxième liste résultants sont dans l'ordre de tri pour les mêmes éléments de la première liste.

Pour éviter le tri basé sur la deuxième liste, spécifiez simplement que seuls les éléments de la première liste doivent être utilisés dans la comparaison des n-uplets:

>>> from operator import itemgetter
>>> list1, list2 = (list(x) for x in Zip(*sorted(Zip(list1, list2),key=itemgetter(0))))
>>> list1, list2
([1, 2, 3, 4, 4, 5, 6], [3, 2, 7, 2, 1, 1, 8])

itemgetter(0) prend le premier élément de chaque tuple, qui appartient à la première liste.

0
ovgolovin