В Python существует множество методов сортировки элементов, но сегодня мы рассмотрим сортировку типов данных в Python с помощью operator.itemgetter и operator.attrgetter.

1. Понимание operator.itemgetter(атрибут) или operator.itemgetter(*атрибут)

Возвращает вызываемый объект, который извлекает элемент из своего операнда __getitem__()

я. Использование itemgetter в словаре для получения пары ключ-значение.

from operator import itemgetter
itemgetter('car_name')({'car_name':'x4','company':'BMW'})
output: 'x4'

II. Использование itemgetter для получения элементов списка.

itemgetter(2)([1,2,3,4,5])
output: 3

2. Понимание operator.attrgetter(атрибут) или operator.attrgetter(*атрибут)

возвращает вызываемый объект, который извлекает атрибут из своего операнда.

from operator import attrgetter
class Movie:
  def __init__(self,name,date):
       self.name = name
       self.date = date
movie = Movie('TheDarkKnight',"2012")

Получение имени и (имя и дата) атрибута объекта фильма

attrgetter('name')(movie)
  Output: 'TheDarkKnight'
attrgetter('name','date')(movie)
  Output: ('TheDarkKnight', '2012')

3. Использование этих функций для сортировки

Ниже представлены фильмы Marvel, выпущенные в апреле, и мы хотим отсортировать их по дате и названию, для чего можем использовать itemgetter.

movies = [{'name':'Avengers Endgame','date':'26/4/2019'},
          {'name':'Iron Man 3','date':'26/4/2013'},
          {'name':'Avengers: Age of Ultron','date':'24/4/2013'}
]

Сортировка по имени

sorted(movies, key=itemgetter('name'))
#equivalent to "sorted(movies, key = lambda x: x['name'])"
Output:[{'name': 'Avengers Endgame', 'date': '26/4/2019'},
 {'name': 'Avengers: Age of Ultron', 'date': '24/4/2013'},
 {'name': 'Iron Man 3', 'date': '26/4/2013'}]

Сортировка по «дате»

sorted(movies, key=itemgetter('date'))
#equivalent to "sorted(movies, key = lambda x: x['date'])"
Output: [{'name': 'Avengers: Age of Ultron', 'date': '24/4/2013'},
 {'name': 'Iron Man 3', 'date': '26/4/2013'},
 {'name': 'Avengers Endgame', 'date': '26/4/2019'}]

Сортировка по эквиваленту «имя» и «дата»

sorted(movies ,key = itemgetter('name','date')) 
#equivalent to "sorted(movies, key = lambda x: (x['name],x['date']))"
[{'name': 'Avengers Endgame', 'date': '26/4/2019'},
 {'name': 'Avengers: Age of Ultron', 'date': '24/4/2013'},
 {'name': 'Iron Man 3', 'date': '26/4/2013'}]

поэтому, как мы видим, и лямбда, и itemgetter имеют одинаковую функциональность, но элемент getter немного быстрее, чем лямбда, поэтому, когда скорость выполнения и память имеют значение, itemgetter рекомендуется.

4. Использование attrgetter для сортировки объектов.

Например, у вас есть объекты, которые необходимо отсортировать в соответствии с одним из их атрибутов, но в python мы не можем сделать это в этот момент, на помощь приходит attrgetter. давайте продолжим тот же пример, что и выше.

class Movie:
    def __init__(self,movie_name,movie_date):
        self.movie_name = movie_name
        self.movie_date = movie_date
    def __repr__(self):
        return 'Movie({},{})'.format(self.movie_name,self.movie_date)
movies = [Movie('Avengers Endgame','26/4/2019'),Movie('Iron Man 3','26/4/2013'), Movie('Avengers: Age of Ultron','24/4/2013')]

Теперь отсортируем кинообъекты по дате выпуска.

sorted(movies,key=attrgetter('movie_date'))
# equavilent to sorted(movies, key= lambda x : x.movie_date)
Output: [Movie(Avengers: Age of Ultron,24/4/2013),
 Movie(Iron Man 3,26/4/2013),
 Movie(Avengers Endgame,26/4/2019)]

Ссылка: Jones, D., 2013. Python Cookbook, 3-е издание. О'Рейли Медиа, Инк.