如何从包含Python中的对象的列表中查找最大值?

时间:2017-07-01 19:59:32

标签: python

我有一个班级:

class Point(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

我创建了上述类Point的对象列表,其中包含字段xy

我想从列表中找到所有对象的xy的最大值。例如,从列表[Point(1,3), Point(5,2), Point(8,0)],它将是8。

我可以这样做:

new_list = []
for point in points_list:
    new_list.append(point.x)
    new_list.append(point.y)

max(new_list)

在Python中最优雅的方法是什么?

4 个答案:

答案 0 :(得分:6)

您可以将max功能与键一起使用:

max_obj = max(your_list, key=lambda p: p.x if p.x > p.y else p.y)

要获得最大值,您可以

max_val = max_obj.x if max_obj.x > max_obj.y else max_obj.y
print(max_val) 

或(如OP建议的那样)......

max_val = max(max_obj.x, max_obj.y)
print(max_val)

答案 1 :(得分:3)

虽然您可以使用像@Coldspeed这样的max()key,但从长远来看,我认为更好的解决方案是让Point的运算符超过运算符类。这样你只需要实现一次逻辑。此外,如果您决定在将来更改逻辑,您只需在一个地方更改它:

>>> class Point(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __gt__(self, point):
        return self.x > point.x or self.y > point.y
    def __lt__(self, point):
        return self.x < point.x or self.y < point.y


>>> points = [Point(1,3), Point(5,2), Point(8,0)]
>>> point = max(points)
>>> point.x
8
>>>

如果您想获得最大值,可以使用简单的三元条件:

max_val = point.x if point.x > point.y else point.y

答案 2 :(得分:2)

如果您可以事先选择要考虑的属性,那么非常简单:

>>> points = [Point(1,3), Point(5,2), Point(8,0)]
>>> max(getattr(p, attr) for p in points for attr in ('x','y'))
8
>>>

答案 3 :(得分:2)

您可以使用vars返回实例属性的字典,然后使用.values方法访问这些值。

>> class Point(object):
...     def __init__(self, x, y):
...         self.x = x
...         self.y = y
... 
>>> points = [Point(1,3), Point(5,2), Point(8,0)]
>>> max_obj = max(points, key=lambda p: max(vars(p).values()))
>>> max_obj.x
8

如果您只对最大值感兴趣,可以执行以下操作:

>>> max(map(lambda p: max(vars(p).values()), points))
8

如果您发现自己经常这样做,那么您可能希望为您的类实现丰富的比较排序方法,并返回一个返回属性最大值的实例方法。

In [7]: import functools

In [8]: @functools.total_ordering
   ...: class Point(object):
   ...:     def __init__(self, x, y):
   ...:         self.x = x
   ...:         self.y = y
   ...:     def max_attr_value(self):
   ...:         return max(vars(self).values())
   ...:     def __eq__(self, other):
   ...:         return self.max_attr_value() == other.max_attr_value()
   ...:     def __lt__(self, other):
   ...:         return self.max_attr_value() < other.max_attr_value()
   ...:     

In [9]: points = [Point(1,3), Point(5,2), Point(8,0)]

In [10]: max(points).max_attr_value()
Out[10]: 8