我有这个具有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的值。 有人能给我一个解释吗?
答案 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 。