У меня есть список объектов Python, которые я хотел бы отсортировать по атрибутам самих объектов. Список выглядит так:
>>> ut
[<Tag: 128>, <Tag: 2008>, <Tag: <>, <Tag: actionscript>, <Tag: addresses>,
<Tag: aes>, <Tag: ajax> ...]
Каждый объект имеет количество:
>>> ut[1].count
1L
Мне нужно отсортировать список по убыванию количества отсчетов.
Я видел несколько методов для этого, но я ищу лучшую практику в Python.
Ответы:
Подробнее о сортировке по ключам .
источник
Можно использовать самый быстрый способ, особенно если в вашем списке много записей
operator.attrgetter("count")
. Однако это может выполняться на предоператорной версии Python, поэтому было бы неплохо иметь запасной механизм. Тогда вы можете сделать следующее:источник
self.__dict__ = {'some':'dict'}
после__init__
метода). Я не знаю, почему все может быть иначе.__dict__
. Обратите внимание, что «объект, имеющий динамически добавленные атрибуты» и «установка__dict__
атрибута объекта » являются почти ортогональными понятиями. Я говорю это, потому что ваш комментарий подразумевает, что установка__dict__
атрибута является обязательным условием для динамического добавления атрибутов.operator.attrgetter
, я мог бы предоставить функцию с любым именем свойства и вернуть отсортированную коллекцию.Читатели должны заметить, что ключ = метод:
во много раз быстрее, чем добавление богатых операторов сравнения к объектам. Я был удивлен, прочитав это (страница 485 «Питона в двух словах»). Вы можете подтвердить это, запустив тесты этой маленькой программы:
Мои, очень минимальные, тесты показывают, что первый сорт более чем в 10 раз медленнее, но в книге говорится, что в целом он примерно в 5 раз медленнее. Причина, по которой они говорят, заключается в высокооптимизируемом алгоритме сортировки, используемом в python ( timsort ).
Тем не менее, очень странно, что .sort (лямбда) быстрее, чем обычный старый .sort (). Я надеюсь, что они исправят это.
источник
__cmp__
эквивалентно вызову.sort(cmp=lambda)
, а не.sort(key=lambda)
так, это не странно вообще.longList2.sort(cmp = cmp)
. Я попробовал это, и это почти так же, как и.sort()
. (Также: обратите внимание, что параметр сортировки "cmp" был удален в Python 3.)Объектно-ориентированный подход
Хорошей практикой является сделать логику сортировки объектов, если это применимо, свойством класса, а не включать его в каждом случае, когда требуется упорядочение.
Это обеспечивает последовательность и устраняет необходимость в шаблонном коде.
Как минимум, вы должны указать
__eq__
и__lt__
операции для этого, чтобы работать. Тогда просто используйтеsorted(list_of_objects)
.источник
__eq__
и__lt__
каковы минимальные требования к реализации?•The sort routines are guaranteed to use __lt__() when making comparisons between two objects...
источник
Это очень похоже на список экземпляров модели Django ORM.
Почему бы не отсортировать их по запросу так:
источник
Добавьте операторы расширенного сравнения в класс объекта, затем используйте метод sort () из списка.
Смотрите богатое сравнение в Python .
Обновление : хотя этот метод будет работать, я думаю, что решение от Triptych лучше подходит для вашего случая, потому что это намного проще.
источник
Если атрибут, по которому вы хотите отсортировать, является свойством , тогда вы можете избежать импорта
operator.attrgetter
и использоватьfget
вместо этого метод свойства .Например, для класса
Circle
со свойствомradius
мы могли бы отсортировать списокcircles
по радиусам следующим образом:Это не самая известная функция, но она часто экономит мне на импорте.
источник