Remove dict from list if one value is equal and another value below

I have a list with dicts with version numbers

my_list = [{'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'}]

In the end, I want only the latest version of each major version on this list and all alpha versions deleted.

my_list = [{'version': 'v1.2.7', 'major': '1.2'},
           {'version': 'v1.3.7', 'major': '1.3'}]

My first thought was to create a new list and iterate through my list, if the major is not on the new list, it will be added, if it is on the new list, it will compare and replace. But I think there may be a more pythonic way to do this.

EDIT: There are also alpha and beta versions that I would like to completely remove from the list.

+4
source share
2 answers

Another case when itertools.groupbycoming to resque:

from itertools import groupby

my_list = [{'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'}]

my_list_ = list(filter(lambda x: all(beta not in x['version'] for beta in ('a', 'b')), my_list))  # removing beta-versions

version_f = lambda y: [0 if any(beta in x for beta in ('a', 'b')) else int(x) for x in y['version'].replace('v', '').split('.')]
grouper = lambda x: x['major']

d = [max(k, key=version_f) for _, k in groupby(sorted(my_list, key=grouper), key=grouper)]
print(d)  # -> [{'version': 'v1.2.7', 'major': '1.2'}, {'version': 'v1.3.7', 'major': '1.3'}, {'version': 'v1.4.1a1', 'major': '1.4'}]

Notes:

  • list. Python.
  • list-comprehension , for. .
  • @Coldspeed, , , , ( {'version': 'v1.3.12', 'major': '1.3'}) lambda 1.

1. Python lists ([1, 3, 10] > [1, 3, 7] True).

+4

. Pythonic :

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'}

(major, latest), , , , dicts.

SetuptoolsVersion

. , , pkg_resources.SetuptoolsVersion. , max sort . is_prerelease True, - -:

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')>}
+2

Source: https://habr.com/ru/post/1689769/


All Articles