我正在浏览一个包含卵的目录,以便将这些卵添加到sys.path。如果目录中有相同的.egg的两个版本,我只想添加最新的版本。
我有一个正则表达式r ^ (? P < eggName > \ w +) - (? P < eggVersion > (\ d \.]+)-.+\.Egg $从文件名中提取名称和版本。问题是比较版本号,它是一个像2.3.1这样的字符串。
因为我比较字符串,2排序超过10,但这是不正确的版本。
>>> "2.3.1" > "10.1.1"
True
我可以做一些拆分、解析、转换为int等,最终我将得到一个变通方法。但这是Python,不是Java。是否有一种优雅的方法来比较版本字符串?
假设你的语义版本是“干净的”(例如,x.x.x),并且你有一个需要排序的版本列表,这里有一些东西可以工作。
# Here are some versions
versions = ["1.0.0", "1.10.0", "1.9.0"]
# This does not work
versions.sort() # Result: ['1.0.0', '1.10.0', '1.9.0']
# So make a list of tuple versions
tuple_versions = [tuple(map(int, (version.split(".")))) for version in versions]
# And sort the string list based on the tuple list
versions = [x for _, x in sorted(zip(tuple_versions, versions))] # Result: ['1.0.0', '1.9.0', '1.10.0']
要获得最新版本,您只需选择列表版本[-1]中的最后一个元素,或者使用sorted()的reverse属性进行反向排序,将其设置为True,并获得[0]元素。
当然,您可以将所有这些打包到一个方便的函数中以供重用。
def get_latest_version(versions):
"""
Get the latest version from a list of versions.
"""
try:
tuple_versions = [tuple(map(int, (version.split(".")))) for version in versions]
versions = [x for _, x in sorted(zip(tuple_versions, versions), reverse=True)]
latest_version = versions[0]
except Exception as e:
print(e)
latest_version = None
return latest_version
print(get_latest_version(["1.0.0", "1.10.0", "1.9.0"]))
将版本字符串转换为元组并从那里开始有什么问题?对我来说已经够优雅了
>>> (2,3,1) < (10,1,1)
True
>>> (2,3,1) < (10,1,1,1)
True
>>> (2,3,1,10) < (10,1,1,1)
True
>>> (10,3,1,10) < (10,1,1,1)
False
>>> (10,3,1,10) < (10,4,1,1)
True
@kindall的解决方案是一个简单的例子,说明代码看起来有多好。
假设你的语义版本是“干净的”(例如,x.x.x),并且你有一个需要排序的版本列表,这里有一些东西可以工作。
# Here are some versions
versions = ["1.0.0", "1.10.0", "1.9.0"]
# This does not work
versions.sort() # Result: ['1.0.0', '1.10.0', '1.9.0']
# So make a list of tuple versions
tuple_versions = [tuple(map(int, (version.split(".")))) for version in versions]
# And sort the string list based on the tuple list
versions = [x for _, x in sorted(zip(tuple_versions, versions))] # Result: ['1.0.0', '1.9.0', '1.10.0']
要获得最新版本,您只需选择列表版本[-1]中的最后一个元素,或者使用sorted()的reverse属性进行反向排序,将其设置为True,并获得[0]元素。
当然,您可以将所有这些打包到一个方便的函数中以供重用。
def get_latest_version(versions):
"""
Get the latest version from a list of versions.
"""
try:
tuple_versions = [tuple(map(int, (version.split(".")))) for version in versions]
versions = [x for _, x in sorted(zip(tuple_versions, versions), reverse=True)]
latest_version = versions[0]
except Exception as e:
print(e)
latest_version = None
return latest_version
print(get_latest_version(["1.0.0", "1.10.0", "1.9.0"]))
基于Kindall的解决方案发布我的完整功能。通过用前导零填充每个版本部分,我能够支持混合在数字中的任何字母数字字符。
虽然肯定不如他的一行函数漂亮,但它似乎可以很好地处理字母数字版本号。(如果您的版本控制系统中有较长的字符串,请确保适当地设置zfill(#)值。)
def versiontuple(v):
filled = []
for point in v.split("."):
filled.append(point.zfill(8))
return tuple(filled)
.
>>> versiontuple("10a.4.5.23-alpha") > versiontuple("2a.4.5.23-alpha")
True
>>> "10a.4.5.23-alpha" > "2a.4.5.23-alpha"
False