对点分隔数字列表进行排序,例如软件版本

107 投票
6 回答
51367 浏览
提问于 2025-04-15 21:13

我有一个包含版本字符串的列表,比如下面这些:

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('.')])

撰写回答