web-dev-qa-db-fra.com

Obtenir la valeur maximale des attributs à partir d'une liste d'objets

J'ai cette liste d'objets qui ont un paramètre x et y (et quelques autres trucs).

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

J'ai besoin d'avoir le maximum y de cette liste. Cependant, j'ai essayé ceci:

print max(path.nodes, key=y)

Et je reçois cette erreur:

NameError: name 'y' is not defined

Je suis un peu nouveau pour Python et les docs ne me donnent aucun indice. Je pense que je me trompe avec le mot-clé parce que si itérer à travers des nœuds comme celui-ci:

for node in path.nodes:
    print node.y

Je vais obtenir les valeurs de y. Quelqu'un pourrait-il me fournir une explication?

31
PDXIII

Pour obtenir uniquement la valeur maximale et non l'intégralité de l'objet, vous pouvez utiliser une expression de générateur:

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

Il y a un intégré pour aider avec ce cas.

import operator

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

Alternativement:

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

Edit: Mais la réponse de Mark Byers est la plus pythonique.

print max(node.y for node in path.nodes)
23
FogleBird
from operator import attrgetter
print max(path.nodes, key=attrgetter("y"))
4
Alexey Kachayev

Si y est un attribut de propriété , vous n'avez même pas besoin d'importer operator.attrgetter. Vous pouvez utiliser la méthode fget à la place:

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

Cela renverra l'instance Node d'où obtenir la valeur max y est juste my_node.y

0
Georgy

y n'est pas défini comme une variable; c'est un attribut d'objets GSNode individuels; vous ne pouvez pas l'utiliser seul comme nom.

Pour accéder aux attributs individuels, vous pouvez utiliser quelque chose comme key=lambda x: x.y Ou attrgetter() à partir du module operator.

0
Wooble