作者suhang (suhang)
看板Python
标题Re: [问题] sorting cmp_to_key
时间Wed Feb 21 06:51:21 2018
原题
http://www.lintcode.com/en/problem/word-sorting/
这题不知道该怎麽用单纯的key去解,所以才想用comparator
不然就得手动写一个merge sort之类的
my solution in Python3
from functools import cmp_to_key
class Solution:
"""
@param alphabet: the new alphabet
@param words: the original string array
@return: the string array after sorting
"""
def wordSort(self, alphabet, words):
# Write your code here
myord = {}
rank = {}
for i, c in enumerate(alphabet):
myord[c] = i
def mycmp(a, b):
length = min(len(a), len(b))
for i in range(length):
if a[i] != b[i]:
return myord[a[i]] - myord[b[i]]
return len(a) - len(b)
words.sort(key = cmp_to_key(mycmp))
return words
※ 引述《uranusjr (←这人是超级笨蛋)》之铭言:
: ※ 引述《suhang (suhang)》之铭言:
: : https://stackoverflow.com/questions/10645986/custom-sort-python
: : 我想将
: : key = lambda word: [alphabet.index(c) for c in word[0]]
: : 这行转换成老式cmp function
: : def mycmp(a, b):
: : return a - b
: : sorted(words, key = cmp_to_key(mycmp))
: : 但是不太会写
: : 请大家提示一下 a, b分别该是什麽? 谢谢
: cmp 与 key 的写法逻辑完全不一样
: 直接转换基本上是行不通的, 重写比较快
: 你必须要仔细想一下你的比对逻辑到底是什麽, 才能写出正确的比较函式
: key 函式是把本来不能比较(或比较法和你想的不同)的东西转换成可比较的东西
: 接着再用转换过的东西排序
: 例如你想把 ['apple', 'orange', 'pear'] 用字串长度排列
: 就会把它们转成字串长度 [5, 6, 4], 排序成 [4, 5, 6] 再转回来
: 那个转换函式就是 key 函式, 在这个例子就是取字串长度的 len()
: cmp 函式则是会一次给你两个输入 a, b 让你比大小
: 如果 a < b 回传负数, a > b 正数, 相等回 0
: 同样用上面的例子, 如果 a = 'apple', b = 'orange' 就要回负数
: 因为 len('apple') < len('orange)
: 在这个状况中, 有个简单的通解可以达成目的
: def cmp_strs(a, b):
: return len(a) - len(b)
: 你把可能的三个输入代进去, 应该就能知道为什麽
: 如同推文提到, cmp 函式并不是特别优秀的功能
: 从上面的例子也可以看出来, cmp 函式的实作方法相对不直觉
: 根据你想要实作的比较, 甚至可能需要很精明的程式码, 需要另外注解来解释
: 除非你需要支援非常旧(不支援 key)的 Python 版本
: 否则几乎永远不应该写 cmp 函式, 而应该使用更简洁易懂的 key 函式
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 8.41.187.50
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/Python/M.1519167083.A.984.html
※ 编辑: suhang (8.41.187.50), 02/21/2018 06:51:59
1F:推 vfgce: 你自己po的key=lambda word:[alphabet.index(c) for c...] 02/21 07:50
2F:→ vfgce: 这个就可以了.你的问题在那? 02/21 07:50
3F:推 vfgce: 化成list,list的比法就是依序比大小... 02/21 07:53
4F:→ vfgce: 前面几个都一样,就看长度,如[1,2]<[1,2,3] 02/21 07:53
5F:→ vfgce: 干嘛自己刻比较方法? 02/21 07:54
一开始comparator写不出来,这篇只是单纯分享我的解法
但是我觉得纯用key funcion应该解不出这题
有人有想法吗?
如果用
words.sort(key = lambda word: [alphabet.index(c) for c in word[0]])
下面这个case会fail
input:
alphebet = "zbadefghijklmnopqrstuvwxyc"
words = ["bca","czb","za","zba","ade"]
return ["za","zba","bca","ade","czb"]
expect ["zba","za","bca","ade","czb"]
※ 编辑: suhang (8.41.187.50), 02/21/2018 08:16:49
6F:推 vfgce: 程式码要改,for c in word[0]是因为它的资料分两部分, 02/21 08:35
7F:→ vfgce: 取第一部分来比,你照抄不改当然错... 02/21 08:35
8F:→ vfgce: 改成for c in word就可以了.... 02/21 08:36
9F:→ vfgce: 你用for c in word[0],只取每个字第一字母,当然错.... 02/21 08:37
10F:→ suhang: Thanks lambda我很少用,实在不熟 谢谢解释 02/21 10:15
11F:→ uranusjr: 所以你已经解了, 那你到底想问什麽问题? 02/21 10:15
12F:→ djshen: 抄别人的好歹去了解一下为什麽这样写吧 02/21 10:18
13F:→ djshen: 问题不一样还照抄 02/21 10:19
14F:推 vfgce: 你对python的资料结构及常用函式还不够熟,多了解一下list, 02/21 12:21
15F:→ vfgce: tuple,set,dict,str有些什麽东西,该怎麽用..另外,别把其他 02/21 12:22
16F:→ vfgce: 程式语言的想法用在python,取较短序列比较的写法用 02/21 12:24
17F:→ vfgce: for aa,bb in zip(a,b):来写即可,多了解一下内建函式, 02/21 12:27
18F:→ vfgce: 忘掉C及java... 02/21 12:27