Your idea
Your idea is actually a good one. It is efficient and can be implemented in a relatively Pythonic way:
import re
releases = [{'version': 'v1.2.3', 'major': '1.2'},
{'version': 'v1.2.7', 'major': '1.2'},
{'version': 'v1.3.7', 'major': '1.3'},
{'version': 'v1.4.1a1', 'major': '1.4'},
{'version': 'v1.3.8b1', 'major': '1.3'},
{'version': 'v1.3.2', 'major': '1.3'}]
stable_releases = [r for r in releases if 'a' not in r['version']
and 'b' not in r['version']]
latest = {}
def major_minor_build(version):
return [int(d) for d in re.findall('\d+', version)]
for release in stable_releases:
version, major = release['version'], release['major']
latest[major] = max([version, latest.get(major, '')],
key=major_minor_build)
print(latest)
# {'1.2': 'v1.2.7', '1.3': 'v1.3.7'}
The output data is a dict of (major, latest)
pairs, which probably is easier to work with than a list of dicts.
SetuptoolsVersion
Versions can be tricky. Instead of reinventing the wheel, we could use pkg_resources.SetuptoolsVersion
. Comparisons are already implemented, so max
and sort
won't need any key. As a bonus, is_prerelease
is True if the version is alpha or beta:
from pkg_resources import SetuptoolsVersion, parse_version
from itertools import groupby
def get_major(release):
return release._version.release[:2]
mylist = [{'version': 'v1.2.3', 'major': '1.2'},
{'version': 'v1.2.7', 'major': '1.2'},
{'version': 'v1.3.7', 'major': '1.3'},
{'version': 'v1.4.1a1', 'major': '1.4'},
{'version': 'v1.3.8b1', 'major': '1.3'},
{'version': 'v1.3.2', 'major': '1.3'}]
releases = [parse_version(r['version']) for r in mylist]
stable_releases = [r for r in releases if not r.is_prerelease]
stable_releases.sort()
print({major:max(group) for major, group in groupby(stable_releases, key=get_major)})
# {(1, 2): <Version('1.2.7')>, (1, 3): <Version('1.3.7')>}