从对象列表中获取属性的最大值

时间:2012-10-25 11:29:55

标签: python list attributes max

我有这个具有x和y参数的对象列表(以及其他一些东西)。

path.nodes = (
    <GSNode x=535.0 y=0.0 GSLINE GSSHARP>,
    <GSNode x=634.0 y=0.0 GSLINE GSSHARP>,
    <GSNode x=377.0 y=706.0 GSLINE GSSHARP>,
    <GSNode x=279.0 y=706.0 GSLINE GSSHARP>,
    <GSNode x=10.0 y=0.0 GSLINE GSSHARP>,
    <GSNode x=110.0 y=0.0 GSLINE GSSHARP>,
    <GSNode x=189.0 y=216.0 GSLINE GSSHARP>,
    <GSNode x=458.0 y=216.0 GSLINE GSSHARP>
)

我需要拥有此列表的最大值。虽然,我试过这个:

print max(path.nodes, key=y)

我收到了这个错误:

NameError: name 'y' is not defined

我是Python的新手,docs没有任何线索。我认为我对关键字做错了,因为如果迭代这样的节点:

for node in path.nodes:
    print node.y

我会得到y的值。 有人能给我一个解释吗?

7 个答案:

答案 0 :(得分:58)

要获得最大值而不是整个对象,可以使用生成器表达式:

print max(node.y for node in path.nodes)

答案 1 :(得分:22)

有一个内置的帮助这个案例。

import operator

print max(path.nodes, key=operator.attrgetter('y'))

可替换地:

print max(path.nodes, key=lambda item: item.y)

编辑:但马克拜尔斯的回答是大多数Pythonic。

print max(node.y for node in path.nodes)

答案 2 :(得分:10)

何时使用&#34; Pythonic&#34;有一个重要的区别。风格#1与lambda风格#2:

max(node.y for node in path.nodes)    (style #1)

max(path.nodes, key=lambda item: item.y)   (style #2)

如果仔细观察,可以看到样式#1返回属性的最大值&#34; y&#34;样式#2返回&#34;节点&#34;具有最大属性&#34; y&#34;。这两个不一样,代码用法很重要,如果你想迭代属性值或迭代拥有该属性的对象。

示例:

class node():
    def __init__(self,x):
        self.x = x
        self.y = self.x + 10

node_lst = [node(1),node(2),node(3),node(4), node(5)]
print ([(e.x,e.y) for e in node_lst])

>>> [(1, 11), (2, 12), (3, 13), (4, 14), (5, 15)]

现在:

maxy = max(node.y for node in node_lst)
print(maxy)
>>> 15

max_node = max(node_lst, key=lambda node: node.y)
print(max_node.y)
>>> 15

答案 3 :(得分:3)

from operator import attrgetter
print max(path.nodes, key=attrgetter("y"))

答案 4 :(得分:0)

y未定义为变量;它是各个GSNode个对象的属性;你不能单独使用它作为名字。

要访问各个属性,您可以使用key=lambda x: x.y模块中的attrgetter()operator

答案 5 :(得分:0)

如果y是属性属性,那么您甚至不需要导入operator.attrgetter。您可以改用fget方法:

my_node = max(path.nodes, key=Node.y.fget)

这将返回Node实例,从那里获取最大y值仅为my_node.y

答案 6 :(得分:0)

还可以为对象实现__gt__比较运算符,然后使用不带键功能的max

class node:
    def __init__(self, y):
        self.y = y
    def __gt__(self, other):
        return self.y > other.y

而不是类似的东西:

ls = [node(3), node(5), node(11), node(0)]
print(max(ls).y)

应该输出 11