Python:从对象列表中获取y的最大值

PDX*_*III 35 python attributes list max

我有这个具有ax和ay参数的对象列表(以及其他一些东西).

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>
)
Run Code Online (Sandbox Code Playgroud)

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

print max(path.nodes, key=y)
Run Code Online (Sandbox Code Playgroud)

我收到这个错误:

NameError: name 'y' is not defined
Run Code Online (Sandbox Code Playgroud)

我是python的新手,doc没有任何线索.我认为我关键字错误,因为如果迭代这样的节点:

for node in path.nodes:
    print node.y
Run Code Online (Sandbox Code Playgroud)

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

Mar*_*ers 62

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

print max(node.y for node in path.nodes)
Run Code Online (Sandbox Code Playgroud)

  • 我会选择`key = lambda x:xy`方式,就像其他方式一样.但**这个**是你真正可以称之为*pythonic*!+1 (2认同)

Fog*_*ird 23

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

import operator

print max(path.nodes, key=operator.attrgetter('y'))
Run Code Online (Sandbox Code Playgroud)

或者:

print max(path.nodes, key=lambda item: item.y)
Run Code Online (Sandbox Code Playgroud)

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

print max(node.y for node in path.nodes)
Run Code Online (Sandbox Code Playgroud)

  • @PDXIII:两个优点:1)`lambda`可以做任何事情,所以维护者必须更仔细地观察它(`lambda item:-item.y`很容易被忽视;`attrgetter`只做一件事,所以知道的维护者它可以速度超过它(这是使用 `operator` 和 `functools` 东西相对于 `lambda` 的一般优势)。2)理论上,`attrgetter` 可以更有效(特别是当它读取多个属性时);在CPython参考解释器中,它是在C层实现的,因此在大多数情况下,字节码解释器根本不会被每个项目调用。 (2认同)

use*_*rix 13

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

max(node.y for node in path.nodes)    (style #1)
Run Code Online (Sandbox Code Playgroud)

max(path.nodes, key=lambda item: item.y)   (style #2)
Run Code Online (Sandbox Code Playgroud)

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

例:

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)]
Run Code Online (Sandbox Code Playgroud)

现在:

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
Run Code Online (Sandbox Code Playgroud)


Ale*_*yev 5

from operator import attrgetter
print max(path.nodes, key=attrgetter("y"))
Run Code Online (Sandbox Code Playgroud)