Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Python中对节号列表进行排序?_Python_List_Sorting - Fatal编程技术网

如何在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。所以我需要第二个键来排序,就像你在回答问题时所做的那样。你回答的问题源于这篇文章(),也许这会让事情变得更清楚。