簡體   English   中英

從對象列表中獲取屬性的最大值

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

我有這個具有 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>
)

我需要有這個列表的最大值。 雖然,我試過這個:

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

我得到這個錯誤:

NameError: name 'y' is not defined

我對 Python 有點陌生,文檔沒有給我任何線索。 我認為我在關鍵字上做錯了,因為如果像這樣遍歷節點:

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

我會得到 y 的值。 有人可以給我一個解釋嗎?

要獲得最大值而不是整個對象,您可以使用生成器表達式:

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

有一個內置工具可以幫助解決這種情況。

import operator

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

或者:

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

編輯:但 Mark Byers 的回答是最 Pythonic 的。

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

何時使用“Pythonic”風格#1 和 lambda 風格#2 有一個重要的區別:

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

相對

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

如果仔細觀察,您會發現 style#1 返回屬性“y”的最大值,而 style#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)]

現在:

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

也可以為對象實現__gt__比較運算符,而不是使用max而不使用 key 函數:

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

y未定義為變量; 它是單個GSNode對象的屬性; 您不能單獨使用它作為名稱。

要訪問各個屬性,您可以使用operator模塊中的key=lambda x: xyattrgetter()之類的內容。

如果y是一個屬性屬性,那么您甚至不需要導入operator.attrgetter 您可以改用fget方法:

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

這將返回Node實例從哪里獲得最大y值只是my_node.y

他們已經回答了您,但是如果您想獲得具有最大值的 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