我有一个班级:
class Point(object):
def __init__(self, x, y):
self.x = x
self.y = y
我创建了上述类Point的对象列表,其中包含字段x
和y
。
我想从列表中找到所有对象的x
或y
的最大值。例如,从列表[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中最优雅的方法是什么?
答案 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