图书部分通常编号为x.x.x
,例如1.2.3
。 如何对部分编号列表进行排序?
将部分编号存储为字符串列表。
# a list of strings, section numbers
ls = ['1.1', '1.10', '1.2', '1.2.3', '1.2.1', '1.9']
lists = sorted([s.split('.') for s in ls], key=lambda x:map(int, x))
# [['1', '1'], ['1', '2'], ['1', '2', '1'], ['1', '2', '3'], ['1', '9'], ['1', '10']]
r = ['.'.join(sublist) for sublist in lists]
#['1.1', '1.2', '1.2.1', '1.2.3', '1.9', '1.10']
然而,我期待的结果是,
['1.1', '1.10', '1.2', '1.2.1', '1.2.3', '1.9']
答案 0 :(得分:7)
使用自定义比较函数将字符串转换为整数子列表。那些将正确排序没有问题。
In [4]: ls = ['1.1', '1.10', '1.2', '1.2.3', '1.2.1', '1.9']
In [5]: def section(s):
...: return [int(_) for _ in s.split(".")]
...:
In [6]: sorted(ls, key=section)
Out[6]: ['1.1', '1.2', '1.2.1', '1.2.3', '1.9', '1.10']
答案 1 :(得分:4)
正如您的评论所述,float
不是您需要的数据类型。在您的情况下,您有章节/部分的实际层次结构。
一个简单的(记住,简单比复杂更好)方法是将节号表示为元组。由于元组按字典顺序排序,它们自然按所需顺序排序:
>>> lf = [(1, ), (1, 1), (1, 10), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (2, ), (1, 9)]
>>> sorted(lf)
[(1, ), (1, 1), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9), (1, 10), (2, )]
正如我们所看到的,这也适用于不同长度的元组。
如果想将这些部分保留为字符串,natsort
也可以很好地处理虚线值:
>>> s = ['1', '1.1', '1.10', '1.2']
>>> natsort.natsorted(s)
['1', '1.1', '1.2', '1.10']
您也可以定义自己的SectionNumber
课程,但这可能有点过分。
答案 2 :(得分:3)
书籍部分通常编号为x.x.x
为什么不将节号存储为元组?
sections = [(2, 4, 1), (1, 10, 3),(1, 2, 1), (1, 1, 10), (1, 2, 3), (1, 4, 6)]
print(sorted(sections))
给出
[(1, 1, 10), (1, 2, 1), (1, 2, 3), (1, 4, 6), (1, 10, 3), (2, 4, 1)]