如何在Python中对节号列表进行排序?
书籍章节通常编号为如何在Python中对节号列表进行排序?,python,list,sorting,Python,List,Sorting,书籍章节通常编号为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
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']
使用自定义比较函数将字符串转换为整数的子列表。这些将正确排序,不会出现问题
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']
书籍章节通常编号为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)]
根据您的评论,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, )]
我们可以看到,这也适用于长度不同的元组
如果希望将节保持为字符串,也可以很好地处理虚线值:
>>> s = ['1', '1.1', '1.10', '1.2']
>>> natsort.natsorted(s)
['1', '1.1', '1.2', '1.10']
您还可以定义自己的
SectionNumber
类,但这可能有点过分。1.10
不是节号,而是一个浮点数。如果需要表示剖面号的对象,请为其创建一个类。使用浮点是个糟糕的主意。输入数据类型错误。节数不是浮点数,它们更像是按字典排序的多项式系数。使用浮动时,1.1
在语义上等于1.10
,但这不是您想要的。将值保留为字符串并按拆分进行排序。或者更好:创建一个合适的类型。为什么不首先将它们存储为字符串?为此使用浮动导致了整个问题1.10==1.1
只要使用数字,就不能使其不成立。这不是数字数据。@sparkandshine我知道你的意思,Python不是。这就是为什么类型很重要。通过使用一个实际的类来编码节号,可以更清楚地说明您的意图。@sparkandshine,这是行不通的。那是一个语法错误!元组的大小可能不同,例如,2.1
和2.1.3
@sparkandshine。。。即使这样,您也会得到正确的排序(2,1)
在之前排序(2,1,3)
,它在(2,2)
之前排序。我可以使用lambda
像排序(ls,key=lambda x:[int()for u.in x.split('.])
?@julivico:当然,这基本上是一样的。@TimPietzcker有办法将此函数与zip函数一起使用。我知道这是不正确的,但它看起来类似于这个结果=列表(zip(*排序(zip(l1键=节,l2,l3,文件\u好\u列表),键=lambda x:float(x[0]))@Jstuff:所以你想把四个列表压缩在一起,并按照与l1
相同的顺序对它们进行排序?第二个键是用来做什么的?是的,但是l1是一个带有浮动值的字符串列表。如果我只做result=list(zip(*排序(zip(l1,l2,l3,files\u good\u list),key=lambda x:float(x[0]))。它将l1排序为1.1、1.10、1.2,而不是1.1、1.2、1.10。所以我需要第二个键来排序,就像你在回答问题时所做的那样。你回答的问题源于这篇文章(),也许这会让事情变得更清楚。