我有一个包含版本号
的dicts的列表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'}]
最后,我希望此列表仅包含每个主要版本的最新版本,并删除所有alpha / beta版本。
my_list = [{'version': 'v1.2.7', 'major': '1.2'},
{'version': 'v1.3.7', 'major': '1.3'}]
我的第一个想法是创建一个新列表并遍历我的列表,如果一个专业不在新列表中,它将被添加,如果它在新列表中,它将进行比较和替换。但我认为可能有更多的pythonic方式。
编辑:还有我想要从列表中删除的alpha和beta版本。
答案 0 :(得分:4)
itertools.groupby
来到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'}]
注意:
list
。你正在覆盖Python内置的。list-comprehension
对您来说太大了,请使用旧的 for
循环将其分解。那里没有犯罪。{'version': 'v1.3.12', 'major': '1.3'}
)并使lambda
更加聪明 1 1。这基于整数lists
的Python内置排序方案([1, 3, 10] > [1, 3, 7]
返回True
)。
答案 1 :(得分:2)
你的想法实际上是一个好主意。它很有效,可以用相对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)
对的字典,可能比一系列字母更容易使用。
版本可能很棘手。我们可以使用pkg_resources.SetuptoolsVersion
而不是重新发明轮子。比较已经实施,因此max
和sort
不需要任何密钥。作为奖励,is_prerelease
如果版本是alpha或beta版,则为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')>}