我正在寻找一种根据自定义字母表对字符串列表进行排序的有效方法。
例如,我有一个字符串字母表"bafmxpzv"
和一个字符串列表,该字符串仅由该字母表中包含的字符组成。
我想要一种方法来排序该列表与其他常见排序类似,但使用此自定义字母表。我怎么能这样做?
答案 0 :(得分:8)
让我们创建一个字母和一个单词列表:
In [32]: alphabet = "bafmxpzv"
In [33]: a = ['af', 'ax', 'am', 'ab', 'zvpmf']
现在让我们根据字母在alphabet
:
In [34]: sorted(a, key=lambda word: [alphabet.index(c) for c in word])
Out[34]: ['ab', 'af', 'am', 'ax', 'zvpmf']
以上按正确顺序排序。
sorted
支持广泛的自定义排序。 sorted
函数有三个可选参数:cmp
,key
和reverse
:
cmp
适用于复杂的排序任务。如果指定,cmp
应该是一个带有两个参数的functionIt。它应返回负数,零或正数,具体取决于第一个参数是否小于,等于或大于第二个参数。对于这种情况,cmp
过度。
key
,如果加速,应该是一个函数,它接受一个参数并返回python本身知道如何排序的东西。在这种情况下,key返回字母表中每个单词字符的索引列表。
在这种情况下,key
会返回alphabet
中字母的索引。
reverse
,如果为true,则反转排序顺序。
从评论中提到了这种替代形式:
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
属于{{1}}。
答案 1 :(得分:1)
更新,我误读了你的问题,你有一个字符串列表,而不是一个字符串,这里是如何做到的,想法是一样的,使用基于自定义比较函数的排序:
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)
答案 2 :(得分:0)
与其使用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']