Подтвердить что ты не робот

Получение максимального значения атрибутов из списка объектов

У меня есть этот список объектов, которые имеют параметр 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

Я получу значения у. Может ли кто-нибудь дать мне объяснение?

4b9b3361

Ответ 1

Чтобы получить только максимальное значение, а не весь объект, вы можете использовать выражение генератора:

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

Ответ 2

В этом случае есть встроенный модуль.

import operator

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

В качестве альтернативы:

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

Изменить: но ответ Марка Байера наиболее Pythonic.

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

Ответ 3

Существует важная разница в том, когда использовать стиль "Pythonic" № 1 по сравнению с лямбда-стилем # 2:

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

против

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

Если вы посмотрите внимательно, вы увидите, что стиль # 1 возвращает максимальное значение для атрибута "y", а стиль # 2 возвращает "node" с максимальным атрибутом "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

Ответ 4

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

Ответ 5

y не определяется как переменная; это атрибут отдельных объектов GSNode; вы не можете использовать его как имя самостоятельно.

Для доступа к отдельным атрибутам вы можете использовать что-то вроде key=lambda x: x.y или attrgetter() из модуля operator.