Я реорганизовал какой-то свой старый код и наткнулся на это:
alist.sort(cmp_items)
def cmp_items(a, b):
if a.foo > b.foo:
return 1
elif a.foo == b.foo:
return 0
else:
return -1
Код работает (и я написал его около 3 лет назад!), Но я не могу найти эту вещь, задокументированную где-либо в документации Python, и все используют sorted()
для реализации настраиваемой сортировки. Может кто-нибудь объяснить, почему это работает?
sorted()
иsort()
предлагают настраиваемую сортировку почти таким же образом, с учетом разницы в соглашениях о вызовах.key
параметра предпочтительнее передачиcmp
функции. (Последний даже не реализован в Python 3)foo
, иначе он взорвется. Лучше определить собственный__lt__()
метод для вашего класса, тогда онsorted()
иlist.sort()
будет работать «из коробки». (Кстати, объекты больше не нужно определять__cmp__()
, просто__lt__()
. См. ЭтоОтветы:
Это задокументировано здесь .
источник
cmp
, я получаюTypeError: 'cmp' is an invalid keyword argument for this function
. Что здесь происходит?sort
функция сравнения не принимает в качестве аргумента в Python 3, а не как то, что я действительно хотел бы сделать.В качестве побочного примечания, вот лучшая альтернатива реализации той же сортировки:
alist.sort(key=lambda x: x.foo)
Или альтернативно:
import operator alist.sort(key=operator.attrgetter('foo'))
Ознакомьтесь с руководством по сортировке , это очень полезно.
источник
Прямо как в этом примере. Вы хотите отсортировать этот список.
[('c', 2), ('b', 2), ('a', 3)]
выход:
[('a', 3), ('b', 2), ('c', 2)]
вы должны отсортировать кортежи по второму элементу, затем по первому:
def letter_cmp(a, b): if a[1] > b[1]: return -1 elif a[1] == b[1]: if a[0] > b[0]: return 1 else: return -1 else: return 1
Затем преобразуйте его в ключевую функцию:
from functools import cmp_to_key letter_cmp_key = cmp_to_key(letter_cmp))
Теперь вы можете использовать свой собственный порядок сортировки:
[('c', 2), ('b', 2), ('a', 3)].sort(key=letter_cmp_key)
источник
Это не работает в Python 3.
Вы можете использовать functools cmp_to_key, чтобы старые функции сравнения работали.
from functools import cmp_to_key def cmp_items(a, b): if a.foo > b.foo: return 1 elif a.foo == b.foo: return 0 else: return -1 cmp_items_py3 = cmp_to_key(cmp_items) alist.sort(cmp_items_py3)
источник
Я знаю, что многие уже опубликовали несколько хороших ответов. Однако я хочу предложить один хороший и простой метод без импорта какой-либо библиотеки.
l = [(2, 3), (3, 4), (2, 4)] l.sort(key = lambda x: (-x[0], -x[1]) ) print(l) l.sort(key = lambda x: (x[0], -x[1]) ) print(l)
Выход будет
[(3, 4), (2, 4), (2, 3)] [(2, 4), (2, 3), (3, 4)]
Вывод будет отсортирован в соответствии с порядком параметров, которые мы предоставили в формате кортежа.
источник
Даже лучше:
student_tuples = [ ('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10), ] sorted(student_tuples, key=lambda student: student[2]) # sort by age [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
Взято с: https://docs.python.org/3/howto/sorting.html
источник