web-dev-qa-db-fra.com

Comment utiliser une fonction de comparaison personnalisée dans Python 3?

Dans Python 2.x, je pouvais passer une fonction personnalisée aux fonctions triées et .sort

>>> x=['kar','htar','har','ar']
>>>
>>> sorted(x)
['ar', 'har', 'htar', 'kar']
>>> 
>>> sorted(x,cmp=customsort)
['kar', 'htar', 'har', 'ar']

Parce que, dans Ma langue, les consonnes sont livrées avec cet ordre

"k","kh",....,"ht",..."h",...,"a"

Mais dans Python 3.x, on dirait que je n'ai pas pu passer le mot clé cmp

>>> sorted(x,cmp=customsort)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'cmp' is an invalid keyword argument for this function

Existe-t-il des alternatives ou dois-je également écrire ma propre fonction triée?

Remarque: j'ai simplifié en utilisant "k", "kh", etc. Le seul problème est que je n'ai pas pu passer ma fonction de comparaison personnalisée à trié ou .sort

75
YOU

Utilisez l'argument key (et suivez la recette sur la façon de convertir votre ancienne fonction cmp en fonction key).

functools a une fonction cmp_to_key mentionné à docs.python.org/3.6/library/functools.html#functools.cmp_to_key

36
Tim Pietzcker

Utilisez le mot clé key et functools.cmp_to_key pour transformer votre fonction de comparaison:

sorted(x, key=functools.cmp_to_key(customsort))
49
aknuds1

Au lieu d'un douaneort (), vous avez besoin d'une fonction qui traduit chaque mot en quelque chose que Python sait déjà trier. Par exemple, vous pouvez traduire chaque mot en une liste de nombres où chaque nombre représente où chaque lettre apparaît dans votre alphabet. Quelque chose comme ceci:

my_alphabet = ['a', 'b', 'c']

def custom_key(Word):
   numbers = []
   for letter in Word:
      numbers.append(my_alphabet.index(letter))
   return numbers

x=['cbaba', 'ababa', 'bbaa']
x.sort(key=custom_key)

Puisque votre langue comprend des lettres à plusieurs caractères, votre fonction custom_key devra évidemment être plus compliquée. Cela devrait vous donner une idée générale.

14
Daniel Stutzbach

Je ne sais pas si cela vous aidera, mais vous pouvez consulter le module locale. Il semble que vous puissiez définir les paramètres régionaux dans votre langue et utiliser locale.strcoll pour comparer les chaînes en utilisant les règles de tri de votre langue.

4
Mark Tolonen

Un exemple complet lambda cmp_to_key python3:

from functools import cmp_to_key

nums = [28, 50, 17, 12, 121]
nums.sort(key=cmp_to_key(lambda x, y: 1 if str(x)+str(y) < str(y)+str(x) else -1))

comparer au tri d'objet commun:

class NumStr:
    def __init__(self, v):
        self.v = v
    def __lt__(self, other):
        return self.v + other.v < other.v + self.v

A = ["12", "121"]
A.sort()
0
Charlie 木匠