简体   繁体   English

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

[英]Getting the max value of attributes from a list of objects

I have this list of objects which have ax and ay parameter (and some other stuff).我有这个具有 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>
)

I need to have the max y of this list.我需要有这个列表的最大值。 Though, I tried this:虽然,我试过这个:

print(max(path.nodes, key=y))

And I get this error:我得到这个错误:

NameError: name 'y' is not defined

I am kinda new to Python and the docs give me no clue.我对 Python 有点陌生,文档没有给我任何线索。 I think I am doing wrong with the keyword because if iterate through nodes like this:我认为我在关键字上做错了,因为如果像这样遍历节点:

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

I'll get the values of y.我会得到 y 的值。 Could somebody provide me an explanation?有人可以给我一个解释吗?

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

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

There's a built-in to help with this case.有一个内置工具可以帮助解决这种情况。

import operator

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

Alternatively:或者:

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

Edit: But Mark Byers' answer is most Pythonic.编辑:但 Mark Byers 的回答是最 Pythonic 的。

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

There is an important difference for when to use the "Pythonic" style#1 versus lambda style#2:何时使用“Pythonic”风格#1 和 lambda 风格#2 有一个重要的区别:

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

versus相对

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

If you look carefully you can see that style#1 returns the maximum value for the attribute "y" while style#2 returns the "node" that has maximum attribute "y".如果仔细观察,您会发现 style#1 返回属性“y”的最大值,而 style#2 返回具有最大属性“y”的“节点”。 These two are not the same and code usage is important in case you want to iterate over the attribute values or iterate over the objects that holds that attribute.这两者不同,如果您想迭代属性值或迭代包含该属性的对象,代码使用很重要。

Example:例子:

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)]

Now:现在:

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
from operator import attrgetter
print max(path.nodes, key=attrgetter("y"))

It's also possible to implement the __gt__ comparison operator for an object, and than use max without a key function:也可以为对象实现__gt__比较运算符,而不是使用max而不使用 key 函数:

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

and than something like:而不是像:

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

is supposed to output 11 .应该输出11

y isn't defined as a variable; y未定义为变量; it's an attribute of individual GSNode objects;它是单个GSNode对象的属性; you can't use it as a name on its own.您不能单独使用它作为名称。

To access the individual attributes you can use something like key=lambda x: xy or attrgetter() from the operator module.要访问各个属性,您可以使用operator模块中的key=lambda x: xyattrgetter()之类的内容。

If y is a property attribute then you don't even need to import operator.attrgetter .如果y是一个属性属性,那么您甚至不需要导入operator.attrgetter You can use fget method instead:您可以改用fget方法:

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

This will return the Node instance from where to get the max y value is just my_node.y这将返回Node实例从哪里获得最大y值只是my_node.y

they already answered you, but if you want to get the object who has the max value:他们已经回答了您,但是如果您想获得具有最大值的 object:

max_val_object = lambda x: max(ob.value for ob in x)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM