如何处理版本列表中包含的字符串导致的错误,按StrictVersion排序?

Posted

技术标签:

【中文标题】如何处理版本列表中包含的字符串导致的错误,按StrictVersion排序?【英文标题】:How to deal with error caused by strings contained in Version list, sorted by StrictVersion? 【发布时间】:2021-10-07 14:53:26 【问题描述】:

我有一个版本列表,我需要使用 Python 中的严格版本库对这些版本进行语义排序。问题是列表中有两个字符串:“未知”和“非版本”,当我运行代码时它们会导致错误。 这是列表

ver_list = ['Unknown' 'Not GAP Version' '4.9.3' '4.9.2' '4.9.1' '4.9.0' '4.9' '4.8.9'
 '4.8.8' '4.8.7' '4.8.6' '4.8.5' '4.8.4' '4.8.3' '4.8.2' '4.8.10' '4.8.1'
 '4.8' '4.7.9' '4.7.8' '4.7.7' '4.7.6' '4.7.5' '4.7.4' '4.7.2' '4.7'
 '4.6.9' '4.6.5' '4.6.4' '4.6.3' '4.6.2' '4.6.12' '4.6.1' '4.6' '4.5.7'
 '4.5.6' '4.5.5' '4.5.4' '4.5.3' '4.5' '4.49' '4.46' '4.4.9' '4.4.7'
 '4.4.6' '4.4.5' '4.4.4' '4.4.3' '4.4.2' '4.4.12' '4.4.11' '4.4.10' '4.4'
 '4.3' '4.2' '4.11.0' '4.11' '4.10.2' '4.10.1' '4.10.0' '4.10' '4.1'
 '3.4.4' '3.4.3' '3.4' '3.3' '3.2' '3.1' '3.0' '1.1' '1.0']

代码如下:

ver_list = ver_list.sort(key=StrictVersion)

错误信息是ValueError 'Unknown' is not a valid version number...

我还尝试将列表转换为 pandas 数据框系列,并使用此处的以下代码 How can i sort semantic versions in pandas? 但我得到了同样的错误信息,这里是当你的版本是你的索引时使用的代码:

ver = ver.reindex(index=pd.Index(sorted(ver.index, key=StrictVersion)))

我只需要对它们进行语义排序,但最终结果还包含“未知”和其他字符串,无论它们是在开头还是结尾。感谢您的帮助,非常感谢。

【问题讨论】:

不是答案。您的ver_list 中是否缺少逗号? 【参考方案1】:

由于StrictVersion 的implementation 使用元组顺序进行比较,您可以围绕StrictVersion 创建一个包装函数,当捕获到异常时返回一个空元组:

def LooserStrictVersion(version):
    try:
        return StrictVersion(version)
    except ValueError:
        return ()

以便您可以使用以下命令对列表进行排序:

ver_list.sort(key=LooserStrictVersion)

【讨论】:

谢谢,这回了TypeError: 'key' is an invalid keyword argument for sort() 您的ver_list 不是您在问题中声称的列表。试试:ver_list = sorted(ver_list, key=StrictVersion) 是的,抱歉,它是 nd.array,已全部排序。【参考方案2】:

由于ver_list 是字符串的list,因此您可以执行此解决方法

ver_list 中删除这两个字符串 - UnknownNot GAP Verison

ver_list.remove('Unknown')
ver_list.remove('Not GAP Version')

根据版本号对ver_list 进行排序

ver_list.sort(key=StrictVersion)

将那些删除的字符串添加回ver_list

arr = ['Unknown', 'Not GAP Version'] 
在末尾添加它们
ver_list = ver_list + arr
在开头添加它们
ver_list = arr + ver_list

代码如下:

from distutils.version import StrictVersion
ver_list = ['Unknown', 'Not GAP Version', '4.9.3', '4.9.2', '4.9.1', '4.9.0', '4.9', '4.8.9','4.8.8', '4.8.7', '4.8.6', '4.8.5','4.8.4','1.10.0', '4.10', '4.1','3.4.4', '3.4.3', '3.4', '3.3', '3.2', '3.1', '13.0', '1.1', '1.0']

# Removing the strings
ver_list.remove('Unknown')
ver_list.remove('Not GAP Version')

# List of removed strings
arr = ['Unknown', 'Not GAP Version']

# Sorting the ver_list
ver_list.sort(key=StrictVersion)

# Adding the removed strings back at the end of ver_list
ver_list = ver_list + arr

print(ver_list)
Output:

['1.0', '1.1', '1.10.0', '3.1', '3.2', '3.3', '3.4', '3.4.3', '3.4.4', '4.1', '4.8.4', '4.8.5', '4.8.6', '4.8.7', '4.8.8', '4.8.9', '4.9.0', '4.9', '4.9.1', '4.9.2', '4.9.3', '4.10', '13.0', 'Unknown', 'Not GAP Version']

【讨论】:

【参考方案3】:

有点骇人听闻的解决方案,但我会实施 StrictVersion 解析方法(请参阅GitHub link)在使用该方法之前抛出错误并手动排除这些错误的检查。然后在最后将它们组合起来。您还可以添加检查以查看是否需要 exception_list 的所有元素,即在本例中为 UnknownNot GAP Version

from distutils.version import StrictVersion
import re

ver_list = ['Unknown', 'Not GAP Version', '4.9.3', '4.9.2', '4.9.1', '4.9.0', '4.9', '4.8.9',
'4.8.8', '4.8.7', '4.8.6', '4.8.5', '4.8.4', '4.8.3', '4.8.2', '4.8.10', '4.8.1',
'4.8', '4.7.9', '4.7.8', '4.7.7', '4.7.6', '4.7.5', '4.7.4', '4.7.2', '4.7',
'4.6.9', '4.6.5', '4.6.4', '4.6.3', '4.6.2', '4.6.12', '4.6.1', '4.6', '4.5.7',
'4.5.6', '4.5.5', '4.5.4', '4.5.3', '4.5', '4.49', '4.46', '4.4.9', '4.4.7',
'4.4.6', '4.4.5', '4.4.4', '4.4.3', '4.4.2', '4.4.12', '4.4.11', '4.4.10', '4.4',
'4.3', '4.2', '4.11.0', '4.11', '4.10.2', '4.10.1', '4.10.0', '4.10', '4.1',
'3.4.4', '3.4.3', '3.4', '3.3', '3.2', '3.1', '3.0', '1.1', '1.0']

exception_list = []

version_re = re.compile(r'^(\d+) \. (\d+) (\. (\d+))? ([ab](\d+))?$',
                            re.VERBOSE | re.ASCII)
for ver in ver_list:
    match = version_re.match(ver)
    if not match:
        exception_list.append(ver)
for i in exception_list:
    ver_list.remove(i)

ver_list.sort(key=StrictVersion)

result = exception_list + ver_list

结果是什么

['Unknown', 'Not GAP Version', '1.0', '1.1', '3.0', '3.1', '3.2', '3.3', '3.4', '3.4.3', '3.4.4', '4.1', '4.2', '4.3', '4.4', '4.4.2', '4.4.3', '4.4.4', '4.4.5', '4.4.6', '4.4.7', '4.4.9', '4.4.10', '4.4.11', '4.4.12', '4.5', '4.5.3', '4.5.4', '4.5.5', '4.5.6', '4.5.7', '4.6', '4.6.1', '4.6.2', '4.6.3', '4.6.4', '4.6.5', '4.6.9', '4.6.12', '4.7', '4.7.2', '4.7.4', '4.7.5', '4.7.6', '4.7.7', '4.7.8', '4.7.9', '4.8', '4.8.1', '4.8.2', '4.8.3', '4.8.4', '4.8.5', '4.8.6', '4.8.7', '4.8.8', '4.8.9', '4.8.10', '4.9.0', '4.9', '4.9.1', '4.9.2', '4.9.3', '4.10.0', '4.10', '4.10.1', '4.10.2', '4.11.0', '4.11', '4.46', '4.49']

【讨论】:

以上是关于如何处理版本列表中包含的字符串导致的错误,按StrictVersion排序?的主要内容,如果未能解决你的问题,请参考以下文章

生命周期如何处理常量字符串/字符串文字?

如何处理 Template Toolkit 中包含非法标识符字符的哈希键?

如何处理不会导致错误的 emptycollectionsException?

如何处理分配的字符串输入?

linux shell 中 如何处理空格的路径?

SQL Server 如何处理非聚集索引中的包含列?