#python #python-3.x #list #sorting #tuples
#python #python-3.x #Список #сортировка #кортежи
Вопрос:
Я пытаюсь отсортировать приведенный ниже список:
list1 = [('a', 1, 3), ('b', 1, 2), ('c', 2, 1)]
на основе 2-го (asc) и 3-го элемента (asc) каждого кортежа, что приводит к:
[('b', 1, 2), ('a', 1, 3), ('c', 2, 1)]
Я попытался использовать:
sorted(list1, key=lambda x: x[1], x[2])
но приводит к ошибке:
SyntaxError: positional argument follows keyword argument
Комментарии:
1. Вам нужно
lambda x:(x[1],x[2])
Ответ №1:
Вот как:
list1 = [('a', 1, 3), ('b', 1, 2), ('c', 2, 1)]
print(sorted(list1, key=lambda x: (x[1], x[2])))
Вывод:
[('b', 1, 2), ('a', 1, 3), ('c', 2, 1)]
Причина, по которой вы получаете ошибку, заключается в запятой в. Видите ли, вместо того, чтобы принимать его как часть lambda
функции, python интерпретирует его, поскольку вы пытаетесь передать в функцию другой аргумент, фактически позиционный аргумент sorted
.
При каждом вызове функции передача аргументов ключевого слова перед позиционными аргументами приведет к указанной вами ошибке.
sorted(list1, key=lambda x: x[1], x[2])
Примечание: срез [1:]
тоже работает:
list1 = [('a', 1, 3), ('b', 1, 2), ('c', 2, 1)]
print(sorted(list1, key=lambda x: x[1:]))
Ответ №2:
Запятая в вашей ключевой лямбде выглядит как конец аргумента для синтаксического анализатора. Заключите его в скобки, чтобы устранить неоднозначность: key=lambda x: (x[1], x[2])
.
В качестве альтернативы, нарезка делает то же самое в этом случае : key=lambda x: x[-2:]
.
Кроме того, хотя это не имеет значения для такого короткого списка operator.itemgetter
, функция незначительно превосходит лямбда-выражение — в прошлый раз, когда я проверял, это было примерно на 10% быстрее в больших списках. key=operator.itemgetter(1, 2)
.
Ответ №3:
Основываясь на сообщении об ошибке, похоже, что интерпретатор интерпретирует key=(lambda x:x[1])
и (x[2])
как второй и третий аргументы sorted()
соответственно. Если вы поместите все лямбда-выражение в круглые скобки, оно должно работать.