计算版本号之间的差异
Calculate the Difference between Version Numbers
this question 的答案帮助我比较了两个版本号字符串并查看哪个版本是 "greater",即更新。
我现在需要做的是计算两个版本号之间的实际差异。主要是查看是否发布了新的主要版本,或者仅发布了次要版本。
"1.3.6" - "1.3.3"
应该 return "0.0.3"
"5.2.0" - "4.0.0"
应该 return "1.2.0"
我可以自己编写一个函数来计算差异(理论上很容易),但是包含所有已经考虑过的情况会很麻烦 pkg_resources,比如版本号之间或末尾的字母.
我看过 pkg_resources 的纪录片,但简单的减法似乎不起作用。对于这个问题是否还有其他已经实施的解决方案?
编辑:好吧,简单的减法没有多大意义,现在我想起来了。它会淡化主要版本和次要版本之间的界限(例如“2.1”-“1.2”=“0.9”,这根本没有帮助)。 (感谢@Jeremy Banks)
好的,感谢您到目前为止的评论,我现在明白了,将版本号作为一个整体进行比较没有意义。
只有比较整个版本号的"fragments"才有意义,即只比较第一部分或第二部分。这就是我可能会做的。
更具体地说:
我将首先查看主要版本(第一部分)是否存在差异。
如果是这种情况,次要版本无关紧要。如果不是这种情况,我将继续比较下一部分版本号。
这个解决方案仍然会让包含版本号包含字母(如“1.8.4b”)的情况变得麻烦,但我想没有办法解决它。
您可以逐个比较:
def compare(a, b):
a_parts = a.split('.')
b_parts = b.split('.')
v = ['major', 'minor', 'build']
for i in range(3):
diff = int(a_parts[i]) - int(b_parts[i])
if diff is 0:
continue
if diff > 0:
direction = 'ahead'
else:
direction = 'behind'
diff = -diff
return 'pkg is %s %s version %s' % (diff, v[i], direction)
return 'version are equal'
print compare('3.2.1', '2.0.0') # pkg is 1 major version ahead
print compare('3.2.1', '3.0.0') # pkg is 2 minor version ahead
print compare('3.2.1', '3.2.0') # pkg is 1 build version ahead
print compare('3.2.1', '3.2.1') # version are equal
print compare('3.2.1', '6.2.1') # pkg is 3 major version behind
如果您的版本号不是标准的(即:1.2b.4321
),您可以使用 parse_version
.
等工具进行预解析
这是我刚刚编写的一个函数,它执行以下操作:
def diffver(v1, v2):
v1s = map(int, v1.split('.'))
v2s = map(int, v2.split('.'))
for ii, (v1r, v2r) in enumerate(zip(v1s, v2s), 1):
if v1r != v2r:
return ii, v1r - v2r
return ii, 0
print diffver("4.0.0", "5.2.0")
print diffver("5.1.0", "5.2.0")
print diffver("5.4.0", "5.2.0")
print diffver("5.4.0", "5.4.0")
它打印:
(1, -1)
(2, -1)
(2, 2)
(3, 0)
想法是 return 一个元组 (PART, DIFF),其中 PART 为 1 表示主要,2 表示次要,等等,DIFF 表示该部分的差异程度。没有区别给你 PART 是比较了多少部分。
也许更紧凑一点:
def compare_versions(ver1, ver2):
numbers1 = [int(x) for x in ver1.split('.')]
numbers2 = [int(x) for x in ver2.split('.')]
return '.'.join(str(v1 - v2) for v1, v2 in zip(numbers1, numbers2))
>>> compare_versions("1.3.6", "1.3.3")
'0.0.3'
>>> compare_versions("5.2.0", "4.0.0" )
'1.2.0'
少一行的变体:
def compare_versions(ver1, ver2):
split_dot = lambda ver: [int(x) for x in ver.split('.')]
return '.'.join(str(v1 - v2) for v1, v2 in zip(split_dot(ver1), split_dot(ver2)))
this question 的答案帮助我比较了两个版本号字符串并查看哪个版本是 "greater",即更新。
我现在需要做的是计算两个版本号之间的实际差异。主要是查看是否发布了新的主要版本,或者仅发布了次要版本。
"1.3.6" - "1.3.3"
应该 return "0.0.3"
"5.2.0" - "4.0.0"
应该 return "1.2.0"
我可以自己编写一个函数来计算差异(理论上很容易),但是包含所有已经考虑过的情况会很麻烦 pkg_resources,比如版本号之间或末尾的字母.
我看过 pkg_resources 的纪录片,但简单的减法似乎不起作用。对于这个问题是否还有其他已经实施的解决方案?
编辑:好吧,简单的减法没有多大意义,现在我想起来了。它会淡化主要版本和次要版本之间的界限(例如“2.1”-“1.2”=“0.9”,这根本没有帮助)。 (感谢@Jeremy Banks)
好的,感谢您到目前为止的评论,我现在明白了,将版本号作为一个整体进行比较没有意义。
只有比较整个版本号的"fragments"才有意义,即只比较第一部分或第二部分。这就是我可能会做的。
更具体地说: 我将首先查看主要版本(第一部分)是否存在差异。 如果是这种情况,次要版本无关紧要。如果不是这种情况,我将继续比较下一部分版本号。
这个解决方案仍然会让包含版本号包含字母(如“1.8.4b”)的情况变得麻烦,但我想没有办法解决它。
您可以逐个比较:
def compare(a, b):
a_parts = a.split('.')
b_parts = b.split('.')
v = ['major', 'minor', 'build']
for i in range(3):
diff = int(a_parts[i]) - int(b_parts[i])
if diff is 0:
continue
if diff > 0:
direction = 'ahead'
else:
direction = 'behind'
diff = -diff
return 'pkg is %s %s version %s' % (diff, v[i], direction)
return 'version are equal'
print compare('3.2.1', '2.0.0') # pkg is 1 major version ahead
print compare('3.2.1', '3.0.0') # pkg is 2 minor version ahead
print compare('3.2.1', '3.2.0') # pkg is 1 build version ahead
print compare('3.2.1', '3.2.1') # version are equal
print compare('3.2.1', '6.2.1') # pkg is 3 major version behind
如果您的版本号不是标准的(即:1.2b.4321
),您可以使用 parse_version
.
这是我刚刚编写的一个函数,它执行以下操作:
def diffver(v1, v2):
v1s = map(int, v1.split('.'))
v2s = map(int, v2.split('.'))
for ii, (v1r, v2r) in enumerate(zip(v1s, v2s), 1):
if v1r != v2r:
return ii, v1r - v2r
return ii, 0
print diffver("4.0.0", "5.2.0")
print diffver("5.1.0", "5.2.0")
print diffver("5.4.0", "5.2.0")
print diffver("5.4.0", "5.4.0")
它打印:
(1, -1)
(2, -1)
(2, 2)
(3, 0)
想法是 return 一个元组 (PART, DIFF),其中 PART 为 1 表示主要,2 表示次要,等等,DIFF 表示该部分的差异程度。没有区别给你 PART 是比较了多少部分。
也许更紧凑一点:
def compare_versions(ver1, ver2):
numbers1 = [int(x) for x in ver1.split('.')]
numbers2 = [int(x) for x in ver2.split('.')]
return '.'.join(str(v1 - v2) for v1, v2 in zip(numbers1, numbers2))
>>> compare_versions("1.3.6", "1.3.3")
'0.0.3'
>>> compare_versions("5.2.0", "4.0.0" )
'1.2.0'
少一行的变体:
def compare_versions(ver1, ver2):
split_dot = lambda ver: [int(x) for x in ver.split('.')]
return '.'.join(str(v1 - v2) for v1, v2 in zip(split_dot(ver1), split_dot(ver2)))