从值是对象列表的字典中查找最小值

时间:2019-05-04 06:54:52

标签: python dictionary

我有一个类服务类型的Python对象列表。还有另一个字典grps,其中根据数据成员将对象分组。同一组中的对象的数据成员具有完全相同的值。

from collections import defaultdict
class service:
    def __init__(self, tasknum, candidatenum, features, cost):
        self.tasknum = tasknum
        self.candidatenum = candidatenum
        self.features = features
        self.cost = cost

s11 = service(1,1, features = [1], cost = 30)
s12 = service(1,2, features = [1], cost = 50)
s13 = service(1,3, features = [1], cost = 70)
s14 = service(1,4, features = [1], cost = 200)
s15 = service(1,5, features = [2], cost = 20)

lst = []
lst.append(s11)
lst.append(s12)
lst.append(s13)
lst.append(s14)
lst.append(s15)

grps = defaultdict(list)
for x in lst:
    grps[tuple(x.features)].append(x)

在上面,有两组,一组对应于features = [1],一组对应于features = [2]

defaultdict(<class 'list'>, {(1,): [<__main__.service object at 0x7efe19a2d6d8>, <__main__.service object at 0x7efe19a2d4e0>, <__main__.service object at 0x7efe1d7e9550>, <__main__.service object at 0x7efe1d7e9588>], (2,): [<__main__.service object at 0x7efe1d7e95c0>]})

对于每个这样的组,我想返回一个具有最小成本值的服务对象,也就是说,在上面,第一组将返回s11服务,第二组将返回{{1} }服务,因为这是该组中唯一的对象。

还有不使用字典就可以做到这一点的更好方法,例如仅使用列表就可以做到吗?

3 个答案:

答案 0 :(得分:4)

在列表理解中,您可以在组的每个成员上调用min(),并使用获取cost属性的键。 operator.attrgetter方便使用:

from operator import attrgetter
# array of min-cost services
mins = [min(g, key = attrgetter('cost')) for g in grps.values()]

# just the costs
[c.cost for c in mins] # [30, 20]

答案 1 :(得分:1)

您可以仅在min()属性的每个子列表上调用cost,然后将这些对象附加到列表中。 min_costs将是成本最低的对象。

#List to hold all objects with min costs
min_costs = []

for k, v in grps.items():
    # Calculate minimum for all sublists on cost attribute
    min_costs.append(min(v, key=lambda x:x.cost))

#Print the costs of objects with min costs
print([c.cost for c in min_costs])
#[30, 20]

一个班轮名单的理解将是相同的

min_costs = [min(v, key=lambda x:x.cost) for v in grps.values()]

答案 2 :(得分:1)

现在您有了字典,请使用min及其参数key找到成本最低的对象:

for k, v in grps.items():
    print(min(v, key=lambda x: x.cost))

# <__main__.service object at 0xeac0f090>
# <__main__.service object at 0xeac0f110>