我有以下列表:
l = [(('01001', '01003'), 4.15),
(('01001', '01005'), 2.83),
(('01001', '01007'), 3.32),
(('01001', '01008'), 2.32),
(('01001', '01009'), 9.32),
(('01001', '01007'), 0.32),
(('01002', '01009'), 6.83),
(('01002', '01011'), 2.53),
(('01002', '01009'), 6.83),
(('01002', '01011'), 2.53),
(('01002', '01009'), 6.83),
(('01002', '01011'), 2.53),
(('01003', '01013'), 20.50),
(('01003', '01013'), 10.50),
(('01003', '01013'), 0.50),
(('01003', '01013'), 2.50),
(('01003', '01013'), 20.30),
(('01003', '01013'), 12.50),
(('01003', '01013'), 1.50),
(('01003', '01013'), 2.40)]我想为此列表的第一个元素选择n个最小值('01001‘、'01002’和'01003')。
我可以用下面的代码计算出最小值:
from itertools import groupby
from statistics import mean
{k:min(v for *_, v in v) for k,v in groupby(result_map, lambda x: x[0][0])}但希望获得3个最小值和要打印的第二列:
预期结果将是如下所示的字典:
{'01001': ['01007', '01008', '01005'], '01002': ['01011', '01009', '01013'] , '01003': ['01013', '01013', ''01013']}任何帮助都将不胜感激!
发布于 2020-09-29 23:47:51
一个非常明确但直截了当的版本。我只对输入列表lst迭代一次
from bisect import bisect_left
from collections import defaultdict
lst = [(('01001', '01003'), 4.15),
...
(('01003', '01013'), 2.40)]
maxlen = 3
ret = defaultdict(list)
val = defaultdict(list)
for ((first, second), value) in lst:
r = ret[first]
v = val[first]
if not r:
r.append(second)
v.append(value)
else:
if value not in v:
idx = bisect_left(v, value)
r.insert(idx, second)
v.insert(idx, value)
if len(r) > maxlen:
ret[first] = r[:3]
val[first] = v[:3]
print(ret) # defaultdict(<class 'list'>, {
# '01001': ['01007', '01008', '01005'],
# '01002': ['01011', '01009'],
# '01003': ['01013', '01013', '01013']})
print(val) # defaultdict(<class 'list'>, {
# '01001': [0.32, 2.32, 2.83],
# '01002': [2.53, 6.83],
# '01003': [0.5, 1.5, 2.4]})其中,我使用defaultdict val来存储与结果res对应的值。
并且我使用bisect模块来查找插入索引idx。
如果值和结果在相同的数据结构中,而不是在ret和val中分隔(例如,一个元组,甚至是一个命名元组),那么设计可能会更好。
https://stackoverflow.com/questions/64121986
复制相似问题