Сортировка по произвольной лямбда
Как я могу отсортировать список по клавише, описанному произвольной функцией? Например, если у меня есть:
mylist = [["quux", 1, "a"], ["bar", 0, "b"]]
Я хотел бы отсортировать "mylist" вторым элементом каждого члена, например
sort(mylist, key=lambda x: x[1])
как я могу это сделать?
Ответы
Ответ 1
У вас в основном есть это:
>>> mylist = [["quux", 1, "a"], ["bar", 0, "b"]]
>>> mylist.sort(key=lambda x: x[1])
>>> print mylist
дает:
[['bar', 0, 'b'], ['quux', 1, 'a']]
Это будет сортировать mylist на месте.
[этот пара отредактирован благодаря коррекции @Daniel.] sorted
вернет новый список, который будет отсортирован, а не будет фактически изменен вход, как описано в http://wiki.python.org/moin/HowTo/Sorting/.
Ответ 2
У вас есть два варианта, очень близкие к тому, что вы описали, на самом деле:
mylist.sort(key=lambda x: x[1]) # In place sort
new_list = sorted(mylist, key=lambda x: x[1])
Ответ 3
Это такая общая потребность, что поддержка для нее была добавлена в стандартную библиотеку в виде operator.itemgetter
:
from operator import itemgetter
mylist = [["quux", 1, "a"], ["bar", 0, "b"]]
mylist.sort(key=itemgetter(1)) # or sorted(mylist, key=...)
Ответ 4
Сортировать и itemgetter является самым быстрым.
>>> import operator
>>> import timeit
>>> mylist = [["quux", 1, "a"], ["bar", 0, "b"]]
>>> t1 = timeit.Timer(lambda: mylist.sort(key=lambda x: x[1]))
>>> t1.timeit()
1.6330803055632404
>>> t2 = timeit.Timer(lambda: mylist.sort(key=operator.itemgetter(1)))
>>> t2.timeit()
1.3985503043467773
>>> t3 = timeit.Timer(lambda: sorted(mylist, key=operator.itemgetter(1)))
>>> t3.timeit()
2.6329514733833292
>>> t4 = timeit.Timer(lambda: sorted(mylist, key=lambda x: x[1]))
>>> t4.timeit()
2.9197154810598533
Ответ 5
Ответ заключается в использовании "отсортированного", т.е.
sorted(mylist, key=lambda x: x[1])
Ответ 6
Решение вашего вопроса: sorted_list = sorted(mylist, key=lambda value:value[1])
Решение для словаря списка:
mylist = [{'name':'kk', 'age':21},{'name':'bk', 'age':21}]
sorted_list = sorted(mylist, key=lambda k: k['key_name'])