2017-02-17 29 views
1

Предположим, у меня есть 5 объектов: obj1 к obj5:Эффективно найти наибольшее значение среди объектов, а также определить объект

obj1.x = 2.7 
obj2.x = 0.9 
obj3.x = 3.8 
obj4.x = 1.2 
obj5.x = 0.4 

Как я могу найти (эффективно) наибольшее значение x, и определить соответствующий obj? Вот ожидаемый ответ будет:

x = 3.8, it belongs to obj3 

Кстати, в конкретном случае, у меня есть 500 объекты.

+0

У вас есть они в списке или какой-то структуре данных? – miradulo

+0

Я опубликовал новый ответ, основанный на предположении, что вы идентифицируете объекты по их индексу в последовательности, а не по имени уникальной переменной. –

+0

@MadPhysicist Спасибо за вашу любезную помощь. Можно ли сортировать объекты, а не только найти максимальный. – aura

ответ

2

Если у вас есть список, и вы должны индекс максимума, вы можете комбинировать max и enumerate сделать эквивалент numpy.argmax в чистом Python:

l = [obj1, obj2, obj3, ...] 
i = max(enumerate(l), key=lambda x: x[1].x)[0] 

i будет индекс, содержащий максимальное значение , так что вы можете распечатать его как

print('x = {}, belongs to obj{}'.format(l[i].x, i + 1)) 

В примере вы дали, i == 2, который печатает x = 3.8, belongs to obj3.

+0

Спасибо @Mad физик. Можно ли сортировать объекты, а не только найти максимальный? – aura

+0

Вы имеете в виду использование 's = sorted (l, key = lambda x: x.x)' ?. В этом случае max будет просто 's [-1]'. Если 'l' является изменяемой последовательностью, такой как' list' (как в моем примере), вы также можете сделать 'l.sort (key = lambda x: x.x)', и в этом случае он будет отсортирован на месте. –

+0

очень приятно. Благодарю. – aura

2

Лучше всего, чтобы поместить их в коллекции (т.е. list, tuple, ..) и использовать max с operator.attrgetter, чтобы захватить объект с максимальным значением x:

from operator import attrgetter 
l = obj1, obj2, obj3, obj4, obj5 
o = max(l, key=attrgetter('x')) 

Значение o возвращается в настоящее время соответствует один с максимальным значением атрибута x, т.е. obj3:

o == obj3 # True 

в идеале, вы не должны «идентификатор «передать» объект с помощью его имени, которое может легко измениться, и если у вас есть список, который не упорядочен по имени, вы получите неправильные результаты.

Вместо этого вы должны указать класс, который был создан из другого атрибута, скажем "name", и определить для него __str__/__repr__, который печатает имя и значение.

+1

Ницца! Всегда приятно использовать 'attrgetter' :) – miradulo

+0

Если вы хотите избежать импорта,' key = lambda x: x.x' отлично работает. –

+0

Слишком плохо, что нет встроенного эквивалента функции «argmax» numpy. –

 Смежные вопросы

  • Нет связанных вопросов^_^