2012-10-25 10 views
19

Ich habe diese Liste von Objekten, die einen x-und y-Parameter (und einige andere Sachen) haben.Python: Max-Wert von y aus einer Liste von Objekten

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

Ich brauche die maximale y dieser Liste. Obwohl, habe ich versucht, dies:

print max(path.nodes, key=y) 

Und ich bekomme diese Fehlermeldung:

NameError: name 'y' is not defined 

Ich bin irgendwie neu zu Python und die doc gibt meine keine Ahnung. Ich glaube, ich tue falsch mit dem Schlüsselwort, denn wenn wie dies durch die Knoten durchlaufen:

for node in path.nodes: 
    print node.y 

Ich werde die Werte von y erhalten. Kann mir jemand eine Erklärung geben?

+0

Wow! Danke Jungs! Das war schnell und gibt mir die Hinweise, die ich brauchte! – PDXIII

+1

@Wtower Vielen Dank für die Bearbeitung. Es ist jetzt viel besser lesbar! – PDXIII

Antwort

36

Um nur den maximalen Wert zu erhalten und nicht das gesamte Objekt können Sie einen Generator Ausdruck verwenden:

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

Ich hätte den 'key = lambda x: x.y' Weg gewählt, genau wie die anderen. Aber ** das ** kannst du wirklich * Python * nennen! +1 –

+1

Dies ist genau das, was ich gesucht habe. Verrückte Syntax! Ich mag das! – PDXIII

14

Es gibt ein eingebautes, um mit diesem Fall zu helfen.

import operator 

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

Alternativ:

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

Edit: Aber Mark Byers' Antwort ist am Pythonic.

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

In meinem Fall war der pythonischste Weg das, wonach ich suchte.Aber gibt es in den anderen Beispielen einen Vorteil des attrgetter() gegenüber dem Lambda-Stil? – PDXIII

1
from operator import attrgetter 
print max(path.nodes, key=attrgetter("y")) 
+1

Das ist in Ordnung, wenn ich das Objekt brauche. Vielen Dank! – PDXIII

0

y nicht als Variable definiert; es ist ein Attribut von einzelnen Objekten GSNode; Sie können es nicht alleine als Namen verwenden.

die individuelle Für den Zugriff auf Attribute, die Sie so etwas wie key=lambda x: x.y oder attrgetter() vom operator Modul verwenden können.

+0

Vielen Dank für die Erklärung! Es wird heller! – PDXIII

2

Es gibt einen wichtigen Unterschied zu, wenn die "Pythonic" style # 1 gegenüber Lambda-Stil # 2 verwenden:

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

gegen

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

Wenn Sie sorgfältig schauen, können Sie diesen Stil sehen # 1 gibt den Maximalwert für das Attribut "y" zurück, während Stil # 2 den "Knoten" zurückgibt, der das maximale Attribut "y" hat. Diese beiden sind nicht identisch und die Codeverwendung ist wichtig, wenn Sie die Attributwerte durchlaufen oder über die Objekte, die dieses Attribut enthalten, iterieren möchten.

Beispiel:

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

Jetzt:

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 
Verwandte Themen