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

Zac*_*ack 62 python

我有一个包含版本字符串的列表,例如:

versions_list = ["1.1.2", "1.0.0", "1.3.3", "1.0.12", "1.0.2"]
Run Code Online (Sandbox Code Playgroud)

我想对它进行排序,结果将是这样的:

versions_list = ["1.0.0", "1.0.2", "1.0.12", "1.1.2", "1.3.3"]
Run Code Online (Sandbox Code Playgroud)

数字的优先顺序显然应该是从左到右,它应该是降序.所以1.2.3来之前2.2.32.2.2之前2.2.3.

我如何在Python中执行此操作?

and*_*opp 121

您还可以使用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)
Run Code Online (Sandbox Code Playgroud)

给你:

['1.0.0', '1.0.2', '1.0.12', '1.1.2', '1.3.3']
Run Code Online (Sandbox Code Playgroud)

它还可以处理带有预发布标签的版本,例如:

versions = ["1.1", "1.1b1", "1.1a1"]
versions.sort(key=StrictVersion)
Run Code Online (Sandbox Code Playgroud)

给你:

["1.1a1", "1.1b1", "1.1"]
Run Code Online (Sandbox Code Playgroud)

文档:https://github.com/python/cpython/blob/3.2/Lib/distutils/version.py#L101

  • 还有distutils.version.LooseVersion这与在字母结尾的版本号多一点宽容["1.0B","1.0.2决赛"],等等诸如此类的东西或者 - 我喜欢这个版本,因为StrictVersion似乎更面向Python distutils特定的版本字符串,LooseVersion迎合了你将在野外看到的更广泛的潜在版本字符串. (19认同)
  • 请注意,“distutils”已被弃用,请参阅 https://www.python.org/dev/peps/pep-0632/。它提到使用“打包”(第三方)。 (6认同)
  • 如果您需要更多自由,可以在StrictVersion上使用distutils.version.LooseVersion.见http://epydoc.sourceforge.net/stdlib/distutils.version.LooseVersion-class.html (3认同)
  • @Dr_Zaszuś 预计会返回“None”,因为它就地排序。请参阅[排序基础](https://docs.python.org/3/howto/sorting.html#sorting-basics)。 (2认同)

Eli*_*sky 80

拆分每个版本字符串以将其作为整数列表进行比较:

versions_list.sort(key=lambda s: map(int, s.split('.')))
Run Code Online (Sandbox Code Playgroud)

给你的清单:

['1.0.0', '1.0.2', '1.0.12', '1.1.2', '1.3.3']
Run Code Online (Sandbox Code Playgroud)

在Python3中map不再返回a list,所以我们需要将它包装在一个list调用中.

versions_list.sort(key=lambda s: list(map(int, s.split('.'))))
Run Code Online (Sandbox Code Playgroud)

这里映射的替代方法是列表理解.有关列表推导的更多信息,请参阅此帖子.

versions_list.sort(key=lambda s: [int(u) for u in s.split('.')])
Run Code Online (Sandbox Code Playgroud)

  • 这是纯粹的优雅. (4认同)
  • 该关键函数在Python 3中不起作用,因为`map`在Python 3中返回迭代器,而不是列表.但这适用于两个版本:`key = lambda s:[int(u)for s in s.split('.')])`. (3认同)
  • 建议您假设读者正在使用 Python 3,并显示 python 2 作为例外(如果需要的话)。 (2认同)

Chr*_*aes 15

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)
Run Code Online (Sandbox Code Playgroud)

['1.0.0', '1.0.2', '1.0.12', '1.1.2', '1.3.3']
Run Code Online (Sandbox Code Playgroud)

但它适用于版本号为的完整软件包名称:

versions = ['version-1.9', 'version-2.0', 'version-1.11', 'version-1.10']
natsorted(versions)
Run Code Online (Sandbox Code Playgroud)

['version-1.9', 'version-1.10', 'version-1.11', 'version-2.0']
Run Code Online (Sandbox Code Playgroud)


Tob*_*old 9

我想同时,有人会用packaging.version它。

例子:

from packaging.version import parse as parseVersion
versions = ['3.1', '0.7.1', '3.4.1', '0.7.7', '0.7.2', '3.3', '3.4.0', '0.7'
            '0.7.5', '0.7.6', '3.0', '3.3.1', '0.7.3', '3.2', '0.7.4']
versions.sort(key = parseVersion)
Run Code Online (Sandbox Code Playgroud)

输出:

['0.7', '0.7.1', '0.7.2', '0.7.3', '0.7.4', '0.7.5', '0.7.6',
 '0.7.7', '3.0', '3.1', '3.2', '3.3', '3.3.1', '3.4.0', '3.4.1']
Run Code Online (Sandbox Code Playgroud)