|
× [PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。 |
|
Pythonでの不満。Python2にあったsorted関数のcmpがなくなって、keyになった。
なぜ、cmpはなくなったのだろうか?考えてみた。 まず、sortedへの不満として、複数キーの昇順・降順ができなくなった。というものがあった。 誤りである。 どうやらkeyにタプルを返すと勝手に複数キーの昇順としてソートしてくれるようだ。 つまり、文字は反転。数字はマイナスにすることで、それらしきものができる。 c=[('a', 1), ('a', 2), ('b', 2), ('b', 1)]
sorted(c, key=lambda x: (tuple(map(lambda z:(0xff-z), x[0].encode("cp932"))), -x[1]))
[('b', 2), ('b', 1), ('a', 2), ('a', 1)]
ここで気づいた。この比較用キーの作成はcmpの場合、ソート方法に依存してしまう。O(2*NlogN)の頻度で比較用キーが作成されてしまうのだ。この点、key指定だと比較用キーはO(N)のみの作成となる。 すばらしい ただし、文字列の降順としては可変長の場合、前述の方法は使えない。なので、classを作ってみた。 class Keys:
def __init__(self, v, isAscs):
self.v = v
self.isAscs = tuple(isAscs)
def __lt__(self, other):
for i, s, isAsc, o in zip(range(len(self.isAscs)-1, -1, -1), self.v, self.isAscs, other.v):
lt = [lambda p1, p2: p1 > p2, lambda p1, p2: p1 < p2][isAsc]
ret = lt(s, o)
if ret or i and lt(o, s):
break
return ret
@staticmethod
def of(isAscs, keymap=lambda x:x):
return lambda item: Keys(keymap(item), isAscs)
if __name__ == "__main__":
arr = [("a", 2), ("b", 1), ("a", 1), ("b", 2)]
print(arr)
#1項目め降順、2項目め昇順
print(sorted(arr, key=Keys.of((False, True))))
#1項目め2文字目昇順、1項目め1文字目昇順
print(sorted(arr, key=Keys.of((True, False), keymap=lambda x:(x[0][1], x[0][0]))))
うん、素晴らしい。PR |
|
|
|
忍者ブログ [PR] |


