gor*_*tde 5 python sorting lambda python-3.x
我使用lambda来修改sort的行为.
sorted(list, key=lambda item:(item.lower(),len(item)))
Run Code Online (Sandbox Code Playgroud)
对包含元素的列表进行排序A1,A2,A3,A,B1,B2,B3,B,结果是A,A1,A2,A3,B,B1,B2,B3.
我预期的排序列表是A1,A2,A3,A,B1,B2,B3,B.
我已经尝试过包含len(item)for sort,但是没有用.如何修改lambda以便排序结果?
这是一种方法:
>>> import functools
>>> def cmp(s, t):
'Alter lexicographic sort order to make longer keys go *before* any of their prefixes'
ls, lt = len(s), len(t)
if ls < lt: s += t[ls:] + 'x'
elif lt < ls: t += s[lt:] + 'x'
if s < t: return -1
if s > t: return 1
return 0
>>> sorted(l, key=functools.cmp_to_key(cmp))
['A1', 'A2', 'A3', 'A', 'B1', 'B2', 'B3', 'B']
Run Code Online (Sandbox Code Playgroud)
传统上,词典排序在其他相同的前缀之后排序更长的字符串(即'abc'在'abcd'之前).
为了满足您的排序期望,我们首先通过添加较长字符串的剩余部分加上另一个字符来"修复"较短的字符串,使其成为两者中的较长者:
compare abc to defg --> compare abcgx to defg
compare a to a2 --> compare a2x to a2
Run Code Online (Sandbox Code Playgroud)
所述functools.cmp_to_key()工具然后转换该比较功能的关键功能.
这可能看起来像很多工作,但排序期望与内置的词典排序规则非常不一致.
FWIW,这是另一种写作方式,可能会或可能不会被认为更清晰:
def cmp(s, t):
'Alter lexicographic sort order to make longer keys go *before* any of their prefixes'
for p, q in zip(s, t):
if p < q: return -1
if q < p: return 1
if len(s) > len(t): return -1
elif len(t) > len(s): return 1
return 0
Run Code Online (Sandbox Code Playgroud)
逻辑是:
我的第一个答案是:只是否定该len标准,仅根据该标准进行反转。
sorted(list, key=lambda item:(item.lower(),-len(item))) # doesn't work!
Run Code Online (Sandbox Code Playgroud)
但这不起作用,因为 alpha 排序和长度之间存在冲突。Alpha 排序将小字符串放在前面。所以长度标准不起作用。
您需要合并这两个标准。彼此之间没有明确的优先顺序。
我找到了一种方法:首先计算字符串的最大长度,然后返回chr(127)字符串的填充(仅使用 ASCII 的最大字符)版本作为键,这样最小的字符串最后会被大字符填充:它们总是最后来。
l = ["A","B","A1","A2","A3","B1","B2","B3"]
maxlen = max(len(x) for x in l)
print(sorted(l, key=lambda item:item.lower()+chr(127)*(maxlen-len(item))))
Run Code Online (Sandbox Code Playgroud)
结果:
['A1', 'A2', 'A3', 'A', 'B1', 'B2', 'B3', 'B']
Run Code Online (Sandbox Code Playgroud)
顺便说一句,出于明显的原因,不要打电话给你的名单list。
| 归档时间: |
|
| 查看次数: |
550 次 |
| 最近记录: |