首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从嵌套的python列表中获取n个最小值

从嵌套的python列表中获取n个最小值
EN

Stack Overflow用户
提问于 2020-09-29 22:42:29
回答 3查看 75关注 0票数 3

我有以下列表:

代码语言:javascript
复制
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')。

我可以用下面的代码计算出最小值:

代码语言:javascript
复制
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个最小值和要打印的第二列:

预期结果将是如下所示的字典:

代码语言:javascript
复制
{'01001': ['01007', '01008', '01005'], '01002': ['01011', '01009', '01013']  , '01003': ['01013', '01013', ''01013']}

任何帮助都将不胜感激!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-09-29 23:14:51

代码语言:javascript
复制
{k:[e[0][1] for e in sorted(v, key = lambda x: x[1])][:n] for k,v in groupby(result_map, lambda x: x[0][0])}

上面是你用groupby提供的代码,但做了一点修改,计算出n个最小的列表,而不是min。

从你的问题的例子中,不清楚你是否想要n个最小列表中的重复元素(第二个条目'01002': ['01011', '01009', '01013']没有重复,但是第三个'01003': ['01013', '01013', ''01013']在你的例子中有重复),所以我提供了第二行代码来解决没有重复的任务:

代码语言:javascript
复制
{k:[e[0][1] for e in sorted({f[0][1] : f for f in v}.values(), key = lambda x: x[1])][:n] for k,v in groupby(result_map, lambda x: x[0][0])}

完整版本的代码can be found and tried online here!

票数 1
EN

Stack Overflow用户

发布于 2020-09-29 22:59:57

下面的代码应该可以工作:

代码语言:javascript
复制
d={i:sorted([k[0][1] for k in l if k[0][0]==i])[:3] for i in set([i[0][0] for i in l])}

print(d)

{'01001': ['01003', '01005', '01007'], '01002': ['01009', '01009', '01009'], '01003': ['01013', '01013', '01013']}
票数 1
EN

Stack Overflow用户

发布于 2020-09-29 23:47:51

一个非常明确但直截了当的版本。我只对输入列表lst迭代一次

代码语言:javascript
复制
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

如果值和结果在相同的数据结构中,而不是在retval中分隔(例如,一个元组,甚至是一个命名元组),那么设计可能会更好。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64121986

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档