如何在Python中正确排序含两位数的软件版本号?
版本号数组正确排序方案
问题描述
我有一组包含字母数字组件的版本号数组,需要将其按从新到旧的顺序排序。但遇到了两位数版本的排序异常问题,例如10.X.X会排在11.X.X之前。尝试了lambda函数以及StrictVersion、natsort、semantic_version等多种方案,都未得到理想结果。
使用的版本数组:
versions = ['11.4.0', '11.3.2', '11.3.1', '11.3.0', '11.2.0', '11.1.0', '11.0.0', '10.16.2', '10.16.1', '10.16.0', '10.15.0', '10.14.1', '10.14.0', '10.13.0', '10.12.0', '10.11.0', '10.10.0', '10.9.1', '10.9.0', '10.8.0', '4.7.6', '4.7.5', '4.7.4', '4.7.3', '4.7.2', '4.7.1', '5.4.0', '5.3.3', '5.3.2', '5.3.1', '5.3.0', '5.2.2', '5.2.1', '5.2.0', '5.1.18', '5.1.17', '5.1.16', '5.1.15', '5.1.13', '5.1.12', '5.1.11', '5.1.10', '5.1.9', '5.1.4', '5.1.0', '5.0.0', '5.9.0', '5.8.0', '5.7.1', '5.7.0', '5.6.5', '5.6.4', '5.6.3', '5.6.2', '5.6.1', '5.6.0', '5.5.9', '5.5.8', '5.5.7', '5.5.6', '5.5.5', '5.5.4', '5.5.3', '5.5.2', '5.5.1', '5.5.0', '7.4.2', '7.4.1', '7.4.0', '7.3.0', '7.2.1', '7.2.0', '7.1.0', '7.0.3', '7.0.2', '7.0.1', '7.0.0', '6.2.0', '6.1.2', '6.1.0', '6.0.0', '5.14.0', '5.13.0', '5.12.0', '5.11.0', '5.10.0', '7.9.5', '7.9.4', '7.9.3', '7.9.2', '7.9.1', '7.9.0', '7.8.4', '7.8.3', '7.8.2', '7.8.1', '7.8.0', '7.7.1', '7.7.0', '7.6.3', '7.6.2', '7.6.1', '7.6.0', '7.5.0', '7.4.4', '7.4.3', '8.3.3', '8.3.2', '8.3.1', '8.3.0', '8.2.0', '8.1.4', '8.1.3', '8.1.2', '8.1.1', '8.1.0', '8.0.8', '8.0.7', '8.0.6', '8.0.5', '8.0.4', '8.0.3', '8.0.2', '8.0.0', '7.9.8', '7.9.7', '9.5.2', '9.5.1', '9.5.0', '9.4.0', '9.3.1', '9.3.0', '9.2.6', '9.2.5', '9.2.4', '9.2.3', '9.2.2', '9.2.1', '9.2.0', '9.1.0', '9.0.0', '8.5.1', '8.5.0', '8.4.0', '8.3.5', '8.3.4', '10.7.0', '10.6.2', '10.6.1', '10.6.0', '10.5.0', '10.4.0', '10.3.0', '10.2.0', '10.1.0', '10.0.5', '10.0.4', '10.0.3', '10.0.1', '10.0.0', '9.8.3', '9.8.2', '9.8.1', '9.8.0', '9.7.0', '9.6.0']
尝试过的方法:
- 使用
distutils.version.StrictVersion:
from distutils.version import StrictVersion def order_versions(versions): return sorted(versions, key=StrictVersion)
- 使用
natsort:
from natsort import natsorted def order_versions(versions): ordered_versions = natsorted(versions, reverse=True) return ordered_versions
- 使用
packaging.version.Version:
from packaging.version import Version def order_versions(versions): ordered_versions = sorted(versions, key=Version, reverse=True) return ordered_versions
当前最佳结果存在的问题:10.X.X系列排在11.X.X之前,不符合从新到旧的排序需求。
解决方案
可以通过自定义排序键来解决这个问题,将版本号拆分为整数元组,然后按元组从大到小排序。这种方法直接对每个版本段的数值进行比较,避免字符串排序的问题。
实现代码:
def order_versions(versions): def version_key(version): # 将版本号按.分割,转换为整数元组 return tuple(map(int, version.split('.'))) # 按元组降序排序 return sorted(versions, key=version_key, reverse=True)
验证结果
调用该函数后,排序结果会将11.X.X系列排在最前面,接着是10.X.X、9.X.X,以此类推,完全符合从新到旧的版本排序逻辑。例如前几项会是:['11.4.0', '11.3.2', '11.3.1', '11.3.0', '11.2.0', '11.1.0', '11.0.0', '10.16.2', ...]
说明
这种自定义键的方式之所以有效,是因为整数比较会正确处理两位数的版本号(比如11大于10),而字符串比较会按字符逐个对比,之前的方法可能因为某些库的实现细节或者使用方式导致异常,直接转换为整数元组的方式更直观且可靠。
内容的提问来源于stack exchange,提问作者Bog Alt
相关产品推荐
相关产品推荐

