在Python中根据自定义字母表排序字符串值
我想找到一种有效的方法来根据自定义的字母表对字符串列表进行排序。
比如说,我有一个字母表是 "bafmxpzv"
,而我的字符串列表只由这个字母表中的字符组成。
我希望能用这个自定义的字母表来排序这个列表,类似于其他常见的排序方法。我该怎么做呢?
3 个回答
与其使用 index()
来查找字符的索引,不如构建一个哈希表,这样在排序时可以直接获取索引,这样更好。
举个例子:
>>> alphabet = "bafmxpzv"
>>> a = ['af', 'ax', 'am', 'ab', 'zvpmf']
>>> order = dict(zip(alphabet, range(len(alphabet))))
>>> sorted(a, key=lambda word: [order[c] for c in word])
['ab', 'af', 'am', 'ax', 'zvpmf']
更新一下,我之前理解错了你的问题,你有一个字符串列表,而不是一个单独的字符串。下面是怎么做的,思路是一样的,使用一个基于自定义比较函数的排序方法:
def acmp (a,b):
la = len(a)
lb = len(b)
lm = min(la,lb)
p = 0
while p < lm:
pa = alphabet.index(a[p])
pb = alphabet.index(b[p])
if pa > pb:
return 1
if pb > pa:
return -1
p = p + 1
if la > lb:
return 1
if lb > la:
return -1
return 0
mylist = ['baf', 'bam', 'pxm']
mylist.sort(cmp = acmp)
让我们先创建一个字母表和一个单词列表:
In [32]: alphabet = "bafmxpzv"
In [33]: a = ['af', 'ax', 'am', 'ab', 'zvpmf']
现在我们来根据字母在字母表中的位置对它们进行排序:
In [34]: sorted(a, key=lambda word: [alphabet.index(c) for c in word])
Out[34]: ['ab', 'af', 'am', 'ax', 'zvpmf']
上面的排序是正确的。
sorted
函数可以进行多种自定义排序。它有三个可选参数:cmp
、key
和 reverse
:
cmp
适合处理复杂的排序任务。如果指定了这个参数,cmp
应该是一个接受两个参数的函数。这个函数会返回一个负数、零或正数,具体取决于第一个参数是比第二个参数小、相等还是大。在这个例子中,使用cmp
有点过于复杂了。key
如果指定了,应该是一个接受一个参数并返回 Python 本身可以理解的排序内容的函数。在这个例子中,key
返回每个单词字符在字母表中的索引列表。也就是说,
key
返回的是字母在alphabet
中的位置。reverse
如果设置为真,就会反转排序的顺序。
一个不工作的替代方案
在评论中提到了一种替代的写法:
In [35]: sorted(a, key=lambda word: [alphabet.index(c) for c in word[0]])
Out[35]: ['af', 'ax', 'am', 'ab', 'zvpmf']
注意,这种写法并不能正确排序。原因是这里的 key
函数只考虑了每个单词的第一个字母。我们可以通过测试 key
来证明这一点:
In [2]: key=lambda word: [alphabet.index(c) for c in word[0]]
In [3]: key('af')
Out[3]: [1]
In [4]: key('ax')
Out[4]: [1]
可以观察到,key
对于两个不同的字符串 af
和 ax
返回了相同的值。返回的值仅反映了每个单词的第一个字符。因此,sorted
无法判断 af
应该排在 ax
前面。