Оставим ли мы этот вопрос стоящим и просто ограничим его область видимости "list-of-lists-of-length-two-встроенные типы (например, string / int / float)" . Или мы также разрешаем «список пользовательских объектов» , как предполагает заголовок, и в этом случае ответом будет «Определить __lt__()метод для вашего класса или наследовать от какого-то класса, который это делает» ? Это сделало бы его намного лучше каноническим.
Ницца. Как вы отметили в комментарии к основному ответу выше, это лучший (только?) Способ сделать несколько сортировок с разными порядками сортировки. Возможно, выделите это. Также в вашем тексте не указано, что вы отсортировали по убыванию по второму элементу.
PeterVermont
2
@ user1700890 Я предполагал, что поле уже было строкой. Он должен сортировать строки в алфавитном порядке по умолчанию. Вы должны опубликовать свой собственный вопрос отдельно в SO, если он не связан конкретно с ответом здесь или с оригинальным вопросом OP.
pbible
5
что означает -в -x[1]?
январь
7
@Jan это обратная сортировка
Jaap
3
Не будет работать в одном конкретном случае. Принятое решение также не будет работать. Например, столбцы, которые будут использоваться в качестве ключей, - это все строки, которые нельзя преобразовать в числа. Во-вторых, нужно отсортировать по возрастанию по одному столбцу и по убыванию по другому столбцу.
coder.in.me
20
Python имеет стабильную сортировку, поэтому при условии, что производительность не является проблемой, самый простой способ - отсортировать ее по полю 2, а затем снова отсортировать по полю 1.
Это даст вам желаемый результат, единственная выгода в том, что, если это большой список (или вы хотите его часто сортировать), дважды вызвать сортировку может быть недопустимо.
Это также облегчает обработку ситуации, когда вы хотите, чтобы некоторые столбцы сортировались в обратном порядке, просто при необходимости включите параметр «reverse = True».
В противном случае вы можете передать несколько параметров в itemgetter или вручную создать кортеж. Вероятно, это будет быстрее, но есть проблема в том, что он плохо обобщается, если некоторые столбцы хотят быть отсортированы в обратном порядке (числовые столбцы все еще можно перевернуть путем их отрицания, но это мешает стабильности сортировки).
Поэтому, если вам не нужны никакие столбцы с обратной сортировкой, перейдите, если хотите, к нескольким аргументам itemgetter, и столбцы не будут числовыми, или вы хотите, чтобы сортировка оставалась стабильной, для нескольких последовательных сортировок.
Изменить: Для комментаторов, у которых есть проблемы с пониманием того, как это отвечает на исходный вопрос, вот пример, который показывает, как именно стабильный характер сортировки гарантирует, что мы можем выполнять отдельные сортировки по каждому ключу и в конечном итоге получим данные, отсортированные по нескольким критериям:
DATA =[('Jones','Jane',58),('Smith','Anne',30),('Jones','Fred',30),('Smith','John',60),('Smith','Fred',30),('Jones','Anne',30),('Smith','Jane',58),('Smith','Twin2',3),('Jones','John',60),('Smith','Twin1',3),('Jones','Twin1',3),('Jones','Twin2',3)]# Sort by Surname, Age DESCENDING, Firstnameprint("Initial data in random order")for d in DATA:print("{:10s} {:10s} {}".format(*d))print('''
First we sort by first name, after this pass all
Twin1 come before Twin2 and Anne comes before Fred''')
DATA.sort(key=lambda row: row[1])for d in DATA:print("{:10s} {:10s} {}".format(*d))print('''
Second pass: sort by age in descending order.
Note that after this pass rows are sorted by age but
Twin1/Twin2 and Anne/Fred pairs are still in correct
firstname order.''')
DATA.sort(key=lambda row: row[2], reverse=True)for d in DATA:print("{:10s} {:10s} {}".format(*d))print('''
Final pass sorts the Jones from the Smiths.
Within each family members are sorted by age but equal
age members are sorted by first name.
''')
DATA.sort(key=lambda row: row[0])for d in DATA:print("{:10s} {:10s} {}".format(*d))
Это работоспособный пример, но для спасения людей, работающих под его управлением, вывод:
Initial data in random order
JonesJane58SmithAnne30JonesFred30SmithJohn60SmithFred30JonesAnne30SmithJane58SmithTwin23JonesJohn60SmithTwin13JonesTwin13JonesTwin23First we sort by first name, after this pass all
Twin1 come before Twin2andAnne comes before FredSmithAnne30JonesAnne30JonesFred30SmithFred30JonesJane58SmithJane58SmithJohn60JonesJohn60SmithTwin13JonesTwin13SmithTwin23JonesTwin23Secondpass: sort by age in descending order.Note that after this pass rows are sorted by age but
Twin1/Twin2andAnne/Fred pairs are still in correct
firstname order.SmithJohn60JonesJohn60JonesJane58SmithJane58SmithAnne30JonesAnne30JonesFred30SmithFred30SmithTwin13JonesTwin13SmithTwin23JonesTwin23Finalpass sorts the Jonesfrom the Smiths.Within each family members are sorted by age but equal
age members are sorted by first name.JonesJohn60JonesJane58JonesAnne30JonesFred30JonesTwin13JonesTwin23SmithJohn60SmithJane58SmithAnne30SmithFred30SmithTwin13SmithTwin23
Обратите внимание, в частности, на то, что на втором шаге reverse=Trueпараметр сохраняет имена первым по порядку, тогда как простая сортировка, а затем обращение к списку приведет к потере желаемого порядка для третьего ключа сортировки.
Стабильная сортировка не означает, что она не забудет, какой была ваша предыдущая сортировка. Этот ответ неверен.
Майк Аксиак
7
Стабильная сортировка означает, что вы можете сортировать по столбцам a, b, c, просто отсортировав по столбцу c, затем b, затем a. Если вы не хотите расширить свой комментарий, я думаю, что вы ошибаетесь.
Дункан
7
Этот ответ, безусловно, правильный, хотя для больших списков он неидеален: если список уже частично отсортирован, вы потеряете большую часть оптимизации сортировки Python, перетасовывая список вокруг еще большего количества. @ Майк, ты не прав; Я предлагаю на самом деле проверить ответы, прежде чем объявлять их неправильными.
Гленн Мейнард
6
@MikeAxiak: docs.python.org/2/library/stdtypes.html#index-29 заявляет в комментарии 9: Начиная с Python 2.3, метод sort () гарантированно будет стабильным. Сортировка является стабильной, если она гарантирует отсутствие изменения относительного порядка элементов, которые сравниваются равными - это полезно для сортировки за несколько проходов (например, сортировка по отделу, а затем по уровню зарплаты).
trapicki
Это не правильно, потому что это не отвечает на вопрос, который он задал. он хочет, чтобы список сортировался по первому индексу, а в случае наличия связей в первом индексе он хочет использовать второй индекс в качестве критерия сортировки. Стабильная сортировка только гарантирует, что при прочих равных условиях исходный заказ будет соответствовать порядку, в котором появляются элементы.
Я не думаю, что tuple()может получить два аргумента (или, скорее, три, если считать с self)
Филипе Коррейя
3
Кортеж принимает только может принять один аргумент
великолепный
1
returnЗаявление должно быть return tuple((x[1], x[2]))или просто return x[1], x[2]. Обратитесь к ответу @jaap ниже, если вы ищете сортировку в разных направлениях
Джо Качикаран
... или tuple(x[1:3]), если вы хотите по какой-то причине использовать конструктор кортежей, а не просто список отображения кортежей x[1], x[2]. Или keyfunc = operator.itemgetter(1, 2)даже не пишите функцию самостоятельно.
Мы также можем использовать .sort с лямбдой 2 раза, потому что сортировка Python установлена и стабильна. Сначала будет отсортирован список по второму элементу x [1]. Затем будет отсортирован первый элемент, x [0] (самый высокий приоритет).
employees[0]=Employee's Name
employees[1] = Employee's Salary
Это эквивалентно выполнению следующих действий: employee.sort (key = lambda x: (x [0], x [1]))
__lt__()
метод для вашего класса или наследовать от какого-то класса, который это делает» ? Это сделало бы его намного лучше каноническим.Ответы:
как это:
источник
operator
это модуль, который нужно импортироватьНе нужно ничего импортировать при использовании лямбда-функций.
Следующие сортировки
list
по первому элементу, затем по второму элементу.источник
-
в-x[1]
?Python имеет стабильную сортировку, поэтому при условии, что производительность не является проблемой, самый простой способ - отсортировать ее по полю 2, а затем снова отсортировать по полю 1.
Это даст вам желаемый результат, единственная выгода в том, что, если это большой список (или вы хотите его часто сортировать), дважды вызвать сортировку может быть недопустимо.
Это также облегчает обработку ситуации, когда вы хотите, чтобы некоторые столбцы сортировались в обратном порядке, просто при необходимости включите параметр «reverse = True».
В противном случае вы можете передать несколько параметров в itemgetter или вручную создать кортеж. Вероятно, это будет быстрее, но есть проблема в том, что он плохо обобщается, если некоторые столбцы хотят быть отсортированы в обратном порядке (числовые столбцы все еще можно перевернуть путем их отрицания, но это мешает стабильности сортировки).
Поэтому, если вам не нужны никакие столбцы с обратной сортировкой, перейдите, если хотите, к нескольким аргументам itemgetter, и столбцы не будут числовыми, или вы хотите, чтобы сортировка оставалась стабильной, для нескольких последовательных сортировок.
Изменить: Для комментаторов, у которых есть проблемы с пониманием того, как это отвечает на исходный вопрос, вот пример, который показывает, как именно стабильный характер сортировки гарантирует, что мы можем выполнять отдельные сортировки по каждому ключу и в конечном итоге получим данные, отсортированные по нескольким критериям:
Это работоспособный пример, но для спасения людей, работающих под его управлением, вывод:
Обратите внимание, в частности, на то, что на втором шаге
reverse=True
параметр сохраняет имена первым по порядку, тогда как простая сортировка, а затем обращение к списку приведет к потере желаемого порядка для третьего ключа сортировки.источник
источник
tuple()
может получить два аргумента (или, скорее, три, если считать сself
)return
Заявление должно бытьreturn tuple((x[1], x[2]))
или простоreturn x[1], x[2]
. Обратитесь к ответу @jaap ниже, если вы ищете сортировку в разных направленияхtuple(x[1:3])
, если вы хотите по какой-то причине использовать конструктор кортежей, а не просто список отображения кортежейx[1], x[2]
. Илиkeyfunc = operator.itemgetter(1, 2)
даже не пишите функцию самостоятельно.Мы также можем использовать .sort с лямбдой 2 раза, потому что сортировка Python установлена и стабильна. Сначала будет отсортирован список по второму элементу x [1]. Затем будет отсортирован первый элемент, x [0] (самый высокий приоритет).
Это эквивалентно выполнению следующих действий: employee.sort (key = lambda x: (x [0], x [1]))
источник
В порядке возрастания вы можете использовать:
или в порядке убывания вы можете использовать:
источник
Сортировка списка диктов с помощью ниже будет сортировать список в порядке убывания по первому столбцу как зарплата и второму столбцу как возраст
Вывод: [{'salary': 123, 'age': 25}, {'salary': 123, 'age': 23}]
источник