简体   繁体   中英

Most Pythonic and Efficient way to compare Version Strings based on meeting a condition

I have a List of lists with two elements ["Name", "Version"] with the name being same for all the lists.

[[N1, V1] , [N1, V2], [N1, V3], [N1,V4], [N1,V5] .....[N1,Vn] ]

I want to have all the [N1,Vi] pairs which are between two versions 'Vx' and 'Vy' which meet the following condition:

Retrieve [N1,Vi] pairs between Vx and Vy only if : Vy > Max(Vi)

(ie When upper limit of versions(Vy) is greater than the maximum value among the versions in the list)

I have tried using :

from distutils.version import LooseVersion, StrictVersion

But I could find only Boolean Results.

[["pshop","4.6.23.1"], ["pshop","4.6.10"], ["pshop","4.0.1"],

 ["pshop","6.8.1"], ["pshop","5.6.23.1"], ["pshop","7.6.23.1"]]

1. If Vx = (5.5.7) Vy = (9.34.1)

In this case it will return lists which have version numbers between Vx and Vy

[["pshop","6.8.1"], ["pshop","5.6.23.1"], ["pshop","7.6.23.1"]]


2. If Vx = (2.5.7) Vy = (6.0.0)

In this case it should return [] as Vy < max(Vi) (6.0.0 < 7.6.23.1)

Use version.parse to parse and compare versions and use a list comprehension to filter the needed versions

>>> from packaging import version
>>> lst = [["pshop","4.6.23.1"], ["pshop","4.6.10"], ["pshop","4.0.1"], ["pshop","6.8.1"], ["pshop","5.6.23.1"], ["pshop","7.6.23.1"]]
>>> compare_ver = lambda x,y: version.parse(x) < version.parse(y)
>>> max_v = max(v for _,v in lst)
>>>
>>> Vx = "2.5.7"; Vy = "9.34.1"
>>> [[n,v] for n,v in lst if compare_ver(Vx, v)] if compare_ver(max_v, Vy) else []
[['pshop', '4.6.23.1'], ['pshop', '4.6.10'], ['pshop', '4.0.1'], ['pshop', '6.8.1'], ['pshop', '5.6.23.1'], ['pshop', '7.6.23.1']]
>>> 
>>> Vx = "2.5.7"; Vy = "6.0.0"
>>> [[n,v] for n,v in lst if compare_ver(Vx, v)] if compare_ver(max_v, Vy) else []
[]

Using distutils :

from distutils.version import LooseVersion

lst = [["pshop","4.6.23.1"], ["pshop","4.6.10"], ["pshop","4.0.1"],
       ["pshop","6.8.1"], ["pshop","5.6.23.1"], ["pshop","7.6.23.1"]]

ver_x, ver_y = '2.5.7', '6.0.0'
mn, mx = LooseVersion(ver_x), LooseVersion(ver_y)
out = [i for i in lst if mn <= LooseVersion(i[1]) <= mx]
print(out)

Prints:

[['pshop', '4.6.23.1'], ['pshop', '4.6.10'], ['pshop', '4.0.1'], ['pshop', '5.6.23.1']]

With:

ver_x, ver_y = '2.5.7', '9.34.1'

Prints:

[['pshop', '4.6.23.1'], ['pshop', '4.6.10'], ['pshop', '4.0.1'], ['pshop', '6.8.1'], ['pshop', '5.6.23.1'], ['pshop', '7.6.23.1']]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM