Как использовать пользовательскую функцию сравнения в Python 3? - PullRequest
70 голосов
/ 28 марта 2010

В Python 2.x , я мог бы передать пользовательскую функцию функциям сортировки и .sort

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

Потому что на моем языке согласные поставляются с этим заказом

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

Но в Python 3.x похоже, что я не смог передать 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

Есть ли альтернативы или я тоже должен написать свою собственную отсортированную функцию?

Примечание: я упростила с помощью "k", "kh" и т. Д. Фактические символы - это Unicodes и даже более сложные, иногда есть гласные до и после согласных, я сделал пользовательскую функцию сравнения, поэтому эта часть в порядке. Только проблема в том, что я не смог передать свою пользовательскую функцию сравнения в sorted или .sort

Ответы [ 6 ]

45 голосов
/ 20 мая 2014

Используйте ключевое слово key и functools.cmp_to_key для преобразования функции сравнения:

sorted(x, key=functools.cmp_to_key(customsort))
34 голосов
/ 28 марта 2010

Используйте аргумент key (и следуйте рецепту , как преобразовать старую функцию cmp в функцию key).

functools имеет функцию cmp_to_key, упомянутую в docs.python.org / 3.6 / library / functools.html # functools.cmp_to_key

13 голосов
/ 28 марта 2010

Вместо customsort () вам нужна функция, которая переводит каждое слово во что-то, что Python уже знает, как сортировать. Например, вы могли бы перевести каждое слово в список чисел, где каждое число представляет, где каждая буква встречается в вашем алфавите. Примерно так:

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)

Поскольку ваш язык содержит многосимвольные буквы, ваша функция custom_key, очевидно, должна быть более сложной. Это должно дать вам общее представление.

4 голосов
/ 28 марта 2010

Не знаю, поможет ли это, но вы можете проверить модуль locale. Похоже, вы можете установить языковой стандарт на свой язык и использовать locale.strcoll для сравнения строк, используя правила сортировки вашего языка.

0 голосов
/ 04 июля 2019

Полный пример Python3 cmp_to_key лямбда:

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))

сравнение с обычной сортировкой объектов:

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 голосов
/ 28 марта 2010

Вместо этого используйте аргумент key. Она берет функцию, которая принимает обрабатываемое значение и возвращает единственное значение, дающее ключ для сортировки.

sorted(x, key=somekeyfunc)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...