对点分隔数字列表进行排序,例如软件版本
我有一个包含版本字符串的列表,比如下面这些:
versions_list = ["1.1.2", "1.0.0", "1.3.3", "1.0.12", "1.0.2"]
我想对它进行排序,最终的结果应该像这样:
versions_list = ["1.0.0", "1.0.2", "1.0.12", "1.1.2", "1.3.3"]
在排序时,数字的优先级应该是从左到右,并且是降序排列。所以 1.2.3
应该排在 2.2.3
之前,而 2.2.2
应该排在 2.2.3
之前。
我该如何在Python中实现这个呢?
6 个回答
30
natsort 提供了一种“自然排序”的方法;这种排序方式非常直观(在 Python 3 中使用)
from natsort import natsorted
versions = ["1.1.2", "1.0.0", "1.3.3", "1.0.12", "1.0.2"]
natsorted(versions)
会得到
['1.0.0', '1.0.2', '1.0.12', '1.1.2', '1.3.3']
而且它也可以对完整的包名和版本号进行排序:
versions = ['version-1.9', 'version-2.0', 'version-1.11', 'version-1.10']
natsorted(versions)
会得到
['version-1.9', 'version-1.10', 'version-1.11', 'version-2.0']
181
Python 3.10+
在Python 3.10及之后的版本中,标准库里的distutils已经被弃用,并且在Python 3.12中完全移除了。你可以查看这个链接了解更多信息。想知道在当前的Python版本中最好的做法,可以参考Tobias Leupold的回答。
Python < 3.10
如果你使用的是Python 3.10之前的版本,可以使用标准库中的distutils.version
模块:
from distutils.version import StrictVersion
versions = ["1.1.2", "1.0.0", "1.3.3", "1.0.12", "1.0.2"]
versions.sort(key=StrictVersion)
这样可以得到:
['1.0.0', '1.0.2', '1.0.12', '1.1.2', '1.3.3']
这个模块也能处理带有预发布标签的版本,比如:
versions = ["1.1", "1.1b1", "1.1a1"]
versions.sort(key=StrictVersion)
这样可以得到:
["1.1a1", "1.1b1", "1.1"]
文档链接:https://github.com/python/cpython/blob/3.2/Lib/distutils/version.py#L101
123
把每个版本字符串拆分开来,方便将它们作为整数列表进行比较:
versions_list.sort(key=lambda s: map(int, s.split('.')))
对于你的列表,结果是:
['1.0.0', '1.0.2', '1.0.12', '1.1.2', '1.3.3']
在Python3中,map
不再返回一个list
,所以我们需要把它放在一个list
的调用里。
versions_list.sort(key=lambda s: list(map(int, s.split('.'))))
这里除了使用map,还可以用列表推导式。想了解更多关于列表推导式的内容,可以查看这篇文章。
versions_list.sort(key=lambda s: [int(u) for u in s.split('.')])