【问题标题】:Most Pythonic and Efficient way to compare Version Strings based on meeting a condition根据满足条件比较版本字符串的最 Pythonic 和最有效的方法
【发布时间】:2026-01-05 19:00:01
【问题描述】:

我有一个列表列表,其中包含两个元素 ["Name", "Version"],所有列表的名称都相同。

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

我想要满足以下条件的两个版本 'Vx' 和 'Vy' 之间的所有 [N1,Vi] 对:

仅在以下情况下检索 Vx 和 Vy 之间的 [N1,Vi] 对:Vy > Max(Vi)

(即版本上限(Vy)大于列表中版本的最大值时)

我尝试过使用:

from distutils.version import LooseVersion, StrictVersion

但我只能找到布尔结果。

[["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)

【问题讨论】:

    标签: python python-3.x python-2.7 version string-comparison


    【解决方案1】:

    使用version.parse 解析和比较版本,并使用列表推导过滤所需的版本

    >>> 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 []
    []
    

    【讨论】:

      【解决方案2】:

      使用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)
      

      打印:

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

      与:

      ver_x, ver_y = '2.5.7', '9.34.1'
      

      打印:

      [['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']]
      

      【讨论】:

      • @ Andrej Kesely,显然它返回整个输入列表,而不是包含范围之间版本的列表。很抱歉造成混乱。
      最近更新 更多