web-dev-qa-db-ja.com

オブジェクトのリストから属性の最大値を取得する

このオブジェクトのリストには、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>
)

このリストの最大yが必要です。しかし、私はこれを試しました:

print max(path.nodes, key=y)

そして、私はこのエラーを受け取ります:

NameError: name 'y' is not defined

私はPythonと docs にまったく新しいことはありません。手掛かりを与えません。

for node in path.nodes:
    print node.y

Yの値を取得します。誰かが私に説明を提供できますか?

31
PDXIII

オブジェクト全体ではなく最大値のみを取得するには、ジェネレーター式を使用できます。

print max(node.y for node in path.nodes)
59
Mark Byers

この場合に役立つビルトインがあります。

import operator

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

代わりに:

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

編集:しかし、マーク・バイヤーズの答えはほとんどPython的です。

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

「Pythonic」スタイル#1とラムダスタイル#2を使用する場合には、重要な違いがあります。

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

versus

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

注意深く見ると、style#1は属性「y」の最大値を返し、style#2は最大属性「y」を持つ「ノード」を返していることがわかります。これら2つは同じではなく、属性値を反復処理する場合、またはその属性を保持するオブジェクトを反復処理する場合、コードの使用は重要です。

例:

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

yがプロパティ属性の場合operator.attrgetterをインポートする必要さえありません。代わりに fget メソッドを使用できます。

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

これは、Nodeの最大値を取得する場所からyのインスタンスを返しますmy_node.y

0
Georgy

yは変数として定義されていません。個々のGSNodeオブジェクトの属性です。単独で名前として使用することはできません。

個々の属性にアクセスするには、operatorモジュールの_key=lambda x: x.y_やattrgetter()などを使用できます。

0
Wooble