web-dev-qa-db-ja.com

Python 3?でカスタム比較関数を使用するには?

Python 2.xでは、ソートされた関数と.sort関数にカスタム関数を渡すことができます

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

なぜなら、My言語では、子音はこの順序で来るからです

"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」などを使用して簡略化しました。実際の文字はUnicodeであり、さらに複雑です。子音の前後に母音が来る場合があります。問題は、カスタム比較関数をsortまたは.sortに渡すことができなかったことだけです

75
YOU

key引数を使用します(そして、古いcmp関数をkey関数に変換する方法について recipe に従います)。

functoolsには docs.python.org/3.6/library/functools.html#functools.cmp_to_key で言及されているcmp_to_key関数があります

36
Tim Pietzcker

keyキーワードと functools.cmp_to_key を使用して、比較関数を変換します。

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

Customsort()の代わりに、各WordをPythonは既にソート方法を知っているものに変換する関数が必要です。例えば、各Wordを各数字の数字のリストに変換できますアルファベットの各文字の位置を表します。次のようなものです。

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関数はより複雑にする必要があります。それはあなたに一般的なアイデアを与えるはずです。

14

これが役立つかどうかはわかりませんが、localeモジュールをチェックアウトできます。ロケールを言語に設定し、locale.strcollを使用して、言語の並べ替え規則を使用して文字列を比較できるようです。

4
Mark Tolonen

完全な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
Charlie 木匠