假设我有一个清单
list = ['aa', 'bb', 'aa', 'aaa', 'bbb', 'bbbb', 'cc']
如果你这样做
list.sort()
你回来
['aa', 'aa', 'aaa', 'bb', 'bbb', 'bbbb', 'cc']
在 python 3 有没有办法我们可以得到
['aaa', 'aa', 'aa', 'bbbb', 'bbb', 'bb', 'cc']
所以在同一个词典组序中,先选择长度较大的。
非常感谢您的帮助!
您可以使用自定义类重新定义小于对字符串的含义。使用该类作为
list.sort
或 sorted
的键。
class C:
def __init__(self, val):
self.val = val
def __lt__(self, other):
min_len = min((len(self.val), len(other.val)))
if self.val[:min_len] == other.val[:min_len]:
return len(self.val) > len(other.val)
else:
return self.val < other.val
lst = ['aa', 'bb', 'aa', 'aaa', 'bbb', 'bbbb', 'cc']
slist = sorted(lst, key=C)
print(slist)
您已经能够用文字解释如何比较两个字符串,因此您可以在 python 中编写这个比较函数。但是,从 python 3 开始,
.sort()
和 sorted()
都需要 key
,而不是比较函数。
您可以通过使用类并定义其方法
.__lt__
将比较函数变成键,如tdelaney的回答;中所述
functools.cmp_to_key
,它是专门为此目的而设计的。
cmp_to_key
需要一个比较函数,对于小于、等于或大于分别返回 -1、0 或 +1。
def custom_compare_strings(s1, s2):
length = min(len(s1), len(s2))
if s1[:length] == s2[:length]:
return len(s2) - len(s1)
else:
return -1 if s1 < s2 else +1
lst = ['aa', 'bb', 'aa', 'aaa', 'bbb', 'bbbb', 'cc']
import functools
slist = sorted(lst, key=functools.cmp_to_key(custom_compare_strings))
print(slist)
# ['aaa', 'aa', 'aa', 'bbbb', 'bbb', 'bb', 'cc']
元组按字典顺序排序,因此您可以使用(字符串的第一个字符,负长度)的元组作为排序键:
list.sort(key=lambda s: (s[0], -len(s)))
def key_highlenfirst(ls):
L = max(map(len,ls))
c = chr(1 + ord(max(c for s in ls for c in s)))
def key(s):
return s + c * max(0, L-len(s))
return key
ls = ['aa', 'bb', 'aa', 'aaa', 'bbb', 'bbbb', 'cc']
ls.sort(key=key_highlenfirst(ls))
print(ls)
# ['aaa', 'aa', 'aa', 'bbbb', 'bbb', 'bb', 'cc']
为了更好地直观地了解其工作原理,这是比较的字符串:
print(sorted(map(key_highlenfirst(ls), ls)))
# ['aaad', 'aadd', 'aadd', 'bbbb', 'bbbd', 'bbdd', 'ccdd']
# All strings were padded with character c='d' to length L=4