Шаг 15.
Python: сборник рецептов. Структуры данных и алгоритмы. Сортировка объектов, не поддерживающих сравнение

    На этом шаге мы рассмотрим один из способов решения этой задачи.

Задача

    Вы хотите отсортировать объекты одного класса, но они не поддерживают операции сравнения.

Решение

    Встроенная функция sorted() принимает аргумент key, в котором может быть передан вызываемый объект, который будет возвращать некоторое значение из объектов, которое sorted() будет использовать для сравнения этих объектов. Например, если у вас в приложении есть последовательность экземпляров класса User и вы хотите отсортировать их по атрибуту user_id, то вы могли бы предоставить вызываемый объект, который принимает экземпляр класса User и возвращает атрибут user_id. Например:

>>> class User:
	def __init__(self, user_id):
		self.user_id = user_id
	def __repr__(self):
		return 'User({})'.format(self.user_id)

	
>>> users = [User(23), User(3), User(99)]
>>> users
[User(23), User(3), User(99)]
>>> sorted(users, key=lambda u: u.user_id)
[User(3), User(23), User(99)]
>>> 

    Вместо lambda можно применить альтернативный подход с использованием operator.attrgetter():

>>> from operator import attrgetter
>>> sorted(users, key=attrgetter('user_id'))
[User(3), User(23), User(99)]
>>> 


Обсуждение

    Использовать или не использовать lambda или attrgetter() - вопрос личных предпочтений. Однако attrgetter() часто оказывается немного быстрее, а также позволяет одновременно извлекать несколько полей. Это аналогично использованию operator.itemgetter() для словарей. Например, если экземпляры класса User также имеют атрибуты first_name и last_name, вы можете выполнить вот такую сортировку:

by_name = sorted(users, key=attrgetter('last_name', 'first_name'

    Стоит отметить, что использованный в этом рецепте прием может быть применен к таким функциям, как min() и max(). Например:

>>> min(users, key=attrgetter('user_id'))
User(3)
>>> max(users, key=attrgetter('user_id'))
User(99)
>>> 

    На следующем шаге мы рассмотрим группирование записей на основе полей.




Предыдущий шаг Содержание Следующий шаг