从对象列表中检索对象的正确方法,其中对象满足某些条件

时间:2014-04-11 17:43:09

标签: python oop

我不太确定如何说出这个问题;抱歉,如果它有误导性或重复。

让我说我有一个班级:

class MyClass(object):
    def __init__(self, num_apples):
        self.apples = num_apples

a = MyClass(1)
b = MyClass(3)
c = MyClass(2)

如果我想找到这些对象中的大多数苹果,那很简单:

group = [a, b, c]
most_apples = max([g.apples for g in group])  # == 3

但是如果我想要检索具有3个苹果而不是3个苹果的对象呢?我可以做类似的事情:

has_most_apples = [g for g in group if g.apples == most_apples][0] # == b

所以我的问题是:有没有更优雅/ pythonic的方法来做到这一点?

实际上现在我已经把它写出来了,它看起来并不那么糟糕。问题仍然存在。我很好奇:)

4 个答案:

答案 0 :(得分:2)

重新阅读你的问题,如果你有多个苹果,你可能想要扩展到过滤功能 -

>>> target_value = 3
>>> a = MyClass(1)
>>> b = MyClass(3)
>>> c = MyClass(2)
>>> d = MyClass(3)
>>> group = [a,b,c,d]
>>> new_group = filter(lambda x : x.apples==target_value,group)
>>> new_group[0] is b
True
>>> new_group[1] is d
True

为了使其可读,您可以实现自己的功能

>>> def get_apples(num_apples):
        return lambda x : x.apples==num_apples
>>> new_group = filter(get_apples(3),group)

答案 1 :(得分:1)

max函数采用key参数来决定如何计算最大值。您可以使用max(group, key=lambda x: x.apples)来获取具有最大apples值的对象。

答案 2 :(得分:0)

其他答案都很好。但要记住你的代码

has_most_apples = [g for g in group if g.apples == most_apples][0]

只会返回苹果数量最多的第一个元素。可能有不止一个可以这样做的卑鄙。

答案 3 :(得分:0)

您可以在apples属性上对列表进行排序,然后选择第一个元素。

from operator import attrgetter

a = MyClass(1)
b = MyClass(3)
c = MyClass(2)

group = [a, b, c]

has_most_apples = sorted(group, key=attrgetter('apples'), reverse=True)[0]

这当然有同样的警告, tdk 提到只返回一个元素,即使有多个具有相同数量的苹果。