web-dev-qa-db-fra.com

Personnalisé Python tri par liste

Je refactais un de mes vieux codes et suis tombé sur ceci:

alist.sort(cmp_items)

def cmp_items(a, b):
    if a.foo > b.foo:
        return 1
    Elif a.foo == b.foo:
        return 0
    else:
        return -1

Le code fonctionne (je l'ai écrit il y a environ 3 ans!), Mais je ne trouve cette chose documentée nulle part dans le Python docs et tout le monde utilise sorted() pour implémenter le tri personnalisé. Quelqu'un peut-il expliquer pourquoi cela fonctionne?

72
Lorenzo

C'est documenté ici .

La méthode sort () utilise des arguments facultatifs pour contrôler les comparaisons.

cmp spécifie une fonction de comparaison personnalisée de deux arguments (éléments de liste) qui doit renvoyer un nombre négatif, nul ou positif, selon que le premier argument est considéré inférieur ou égal au second argument: cmp = lambda x, y : cmp (x.lower (), y.lower ()). La valeur par défaut est Aucune.

51
miles82

En passant, voici une meilleure alternative pour mettre en œuvre le même tri:

alist.sort(key=lambda x: x.foo)

Ou bien:

import operator
alist.sort(key=operator.attrgetter('foo'))

Découvrez le Comment trier , c'est très utile.

89
Andrew Clark

Juste comme cet exemple. Vous voulez trier cette liste.

[('c', 2), ('b', 2), ('a', 3)]

sortie:

[('a', 3), ('b', 2), ('c', 2)]

vous devriez trier les tuples par le second élément, puis le premier:

def letter_cmp(a, b):
    if a[1] > b[1]:
        return -1
    Elif a[1] == b[1]:
        if a[0] > b[0]:
            return 1
        else:
            return -1
    else:
        return 1

Finalement:

juste sort(letter_cmp)

10
RryLee

Cela ne fonctionne pas dans Python 3.

Vous pouvez utiliser functools cmp_to_key pour que les fonctions de comparaison d’ancien style fonctionnent.

from functools import cmp_to_key

def cmp_items(a, b):
    if a.foo > b.foo:
        return 1
    Elif a.foo == b.foo:
        return 0
    else:
        return -1

cmp_items_py3 = cmp_to_key(cmp_items)

alist.sort(cmp_items_py3)
3
The Unfun Cat