在Python中按(XX-YY)格式排序数字集合
我有一个Python列表,里面的值都是这种格式:
CCXX-YY,其中CC是两个字母,所有的值都是一样的,X是一个数字,YY也是数字。
比如:
KA13-1 KA13-2 KA14-2 KA14-1 KA11-12 KA13-11
变成
KA11-12 KA13-1 KA13-2 KA13-11 KA14-1 KA14-2
而不是
KA11-12 KA13-1 KA13-11 KA13-2 KA14-1 KA14-2
我尝试过的办法:
natsort(遇到的问题是把-当成了负号)
后来补充:如果使用参数alg=ns.UNSIGNED,natsort可以正常工作,下面有说明。
naturalsort(在Python 3中不太好用?)
用关键字排序(我知道这样可以做到,但我对Python还不太熟悉,搞不定)
我现在正在尝试的办法:
去掉除了数字以外的所有多余字段,试着根据数字排序(这个有点问题,因为KA12-10会排在KA14-1后面,因为1210比141大)
我不能轻易地把值改成不带连字符的格式,因为我从网站请求数据时需要保持原来的格式,以便查询单个项目。
我相信有经验的人能帮我解决内置排序的问题。
谢谢。
4 个回答
1
更新的回答
从 natsort 版本 4.0.0 开始,这个功能可以直接使用,不需要特别的选项。
>>> from natsort import natsorted
>>> natsorted('KA11-12 KA13-1 KA13-11 KA13-2 KA14-1 KA14-2'.split())
['KA11-12', 'KA13-1', 'KA13-2', 'KA13-11', 'KA14-1', 'KA14-2']
旧的回答 针对 natsort 版本小于 4.0.0
你提到过因为负号的问题,natsort 对你来说不管用。这是因为默认情况下,负号 '-' 被当作后面数字的一部分来处理,但你可以通过使用 "UNSIGNED" 这个选项来关闭这个功能。
>>> from natsort import natsorted, ns
>>> natsorted('KA11-12 KA13-1 KA13-11 KA13-2 KA14-1 KA14-2'.split(), alg=ns.UNSIGNED)
['KA11-12', 'KA13-1', 'KA13-2', 'KA13-11', 'KA14-1', 'KA14-2']
使用 versorted
也可以解决这个问题。
>>> from natsort import versorted
>>> versorted('KA11-12 KA13-1 KA13-11 KA13-2 KA14-1 KA14-2'.split())
['KA11-12', 'KA13-1', 'KA13-2', 'KA13-11', 'KA14-1', 'KA14-2']
我得坦白一下,我是 natsort
的作者。
1
如果你只想考虑整数部分来进行排序:
l = ['KB13-1', 'KA13-2', 'KC11-11', 'KA14-1', 'KA11-12']
sorted(l, key=lambda i: i[2:])
输出结果
['KC11-11', 'KA11-12', 'KB13-1', 'KA13-2', 'KA14-1']
如果前两个字符永远不变,那么你可以直接使用普通的 sort
或 sorted
函数。
x = ['KA13-1', 'KA13-2', 'KA11-11', 'KA14-1', 'KA11-12']
sorted(x)
输出结果
['KA11-11', 'KA11-12', 'KA13-1', 'KA13-2', 'KA14-1']
2
我觉得真正的问题是,你希望像 KA13-12
这样的东西放在哪里。如果你希望它排在 KA13-2
后面,那么你可能需要类似下面的东西:
>>> seq = "KA13-1 KA13-2 KA14-2 KA14-1 KA11-12 KA13-12".split()
>>> seq.sort(key=lambda x: tuple(map(int, x[2:].split("-"))))
>>> seq
['KA11-12', 'KA13-1', 'KA13-2', 'KA13-12', 'KA14-1', 'KA14-2']