Сортировки и лямбда-функции
У стандартной сортировки (метода sort списка, функции sorted) есть более универсальный способ задания порядка сортировки при помощи параметра key. Значение этого параметра некоторая функция, которая вызывается для каждого элемента, перед сравнением этих элементов: элементы списка сортируются, но сравниваются не значения элементов, а результат вызова переданной функции от этого элемента.
Например, пусть дан список строк, содержащих цифры, нужно упорядочить элементы списка, сравнивая их, как числа, а не как строки. Это можно сделать так:
a = ["10", "20", "30", "1", "2", "3", "111", "112", "222"] a.sort(key=int)
В сложных случаях функцию нужно написать самостоятельно, например, пусть дан список чисел, который нужно упорядочить по последней цифре. Напишем функцию, которая возвращает последнюю цифру числа:
def last_digit(n): return n % 10 a.sort(key=last_digit)
Параметр key можно использовать вместе с параметром reverse .
Лямбда-функции
В предыдущем примере пришлось создавать отдельную функцию только для того, чтобы задать порядок сортировки, что захламляет программу ненужными функциями. В таких случаях нужно использовать лямбда-функции: “одноразовые фукцнии, которые можно объявлять без использовать слова def , прямо при вызове сортировки. Лямбда-функция — это функция, которая состоит только из одной строки с инструкцией return , то есть функция сразу возвращает значение по набору аргументов. Лямбда-функции объявляются таким образом:
lambda список переменных-аргументов: возвращаемое значение
Например, отсортировать список чисел по последней цифре можно при помощи следующей лямбда-функции:
a = [3, 15, 22, 13, 12, 32, 45, 43] a.sort(key=lambda n: n % 10)
Рассмотрим другой пример. Пусть дан список точек, каждая точка: кортеж из двух чисел. Например, [(3, -2), (7, 1), (0, 4)] . Этот список нужно отсортировать по возрастанию расстояния от начала координат до точки. Напишем лямбда-функцию:
a.sort(key=lamda point: point[0] ** 2 + point[1] ** 2)
Элементами списка являются кортежи из двух координат, можно обратиться к этим координатам по индексам [0] и [1].
Устойчивость сортировки
Вернёмся к примеру сортировки по последней цифре. В приведённом выше примере упорядоченный список будет таким:
[22, 12, 32, 3, 13, 43, 15, 45]
Этот пример иллюстрирует свойство устойчивости сортировки: функция сортировки не переставлят элементы, если они равны друг другу. В данном случае функция упорядочивает числа по последней цифре, а при равной последней цифре сохраняется порядок следования элементов в исходном списке: 22, 12, 32.
Что делать, если нужно сделать сложную сортировку, учитывающую несколько критериев? Например, при равной последней цифре нужно упорядочить элементы в порядке возрастания самих чисел.
Первый способ решения: напишем функцию, которая будет возвращать кортеж из двух чисел: последней цифры и самого числа. Кортежи сравниваются в лексикографическом порядке, поэтому при равенстве остатка от деления будут сравниваться сами числа.
a.sort(key=lambda n: (n % 10, n))
Второй способ: воспользуемся устойчивостью сортировки. Отстортируем список сначала по возрастанию чисел, а затем — по последней цифре. Тогда при равном значении последней цифры сохранится ранее полученный порядок.
a.sort() a.sort(key=lambda n: n % 10)
То есть сортировку по \(k\) параметрам (если по первому параметру элементы равны, то сравнить по второму, если равны два параметра, то сравнить по третьему и т.д.) можно заменить на \(k\) последовательных сортировок, выполняющихся в обратном порядке (от наименее значимого параметра к наиболее значимому).
Функция operator.itemgetter
При сортировке кортежей частой задачей является сортировка по какому-то одному элементу кортежа. Например, если нужно отсортировать кортежи по элементу с индексом 1, то можно написать такую лямбда-функцию:
a.sort(key=lambda elem: elem[1])
Для удобства в модуле operator есть функция itemgetter , которая позволяет создавать подобные функции, а именно, функция реализована примерно так:
def itemgetter(i): return lambda elem: elem[i]
То есть operator.itemgetter(i) — это функция, при вызове которой от числового параметра создаётся лямдба-функция, которую можно использовать в качестве параметра key . Если вызвать функцию itemgetter от нескольких параметров, то полученная функция будет возвращать кортеж из элементов с заданными индексами.
Сортировка по алфавиту и длине сразу
Исходные данные: есть файл .txt, в нем записаны слова через строчку, например:
aaa\n c\n bb\n aa\n a\n cc\n bbb\n b\n ccc\n
Цель: сделать сортировку по алфавиту и длине строк. Вопрос: Пока что код есть такой, не знаю как правильно задать ключу сортировки, чтобы выполнялась сортировка так, как нужно, помогите, пожалуйста. Данный код выполняет сортировку только по длине строк..
open_file = open('testlist.txt', 'r').readlines() save_file = open('testlist_sorted.txt', 'w') for line in sorted(open_file, key=len): save_file.write(line)
Буду благодарен вашей помощью! С уважением, Иван.
Python: сортировка списков методом .sort() с ключом — простыми словами
Поводом опубликовать пост стало то, что при детальном изучении списков (массивов) в Python я не смог найти в сети ни одного простого описания метода сортировки элементов с использованием ключа: list.sort(key=. ).
Может быть, конечно, это мне так не повезло и я долго понимаю простые для всех вещи, однако я думаю, что приведенная ниже информация будет весьма полезна таким же начинающим питонистам, как и я сам.
Итак, что мы имеем. Предположим, у нас есть список, который мы бы хотели отсортировать — и состоит он из трех строк разной длины в определенной последовательности:
sortList = [‘a’, ‘сс’, ‘bbb’]
Сортировка элементов массива методом .sort() производится по умолчанию лексикографически — проще говоря, в алфавитном порядке, а также от меньшего значения к большему. Поэтому если мы выполним:
то получим на выходе:
Однако метод .sort() позволяет нам изменять и принцип, и порядок сортировки.
Для изменения принципа сортировки используется ключевое слово key, которое стало доступным начиная с версии Python 2.4.
Предположим, нам хотелось бы отсортировать наш список двумя способами: 1. в алфавитном порядке; 2. по длине строки. Первый способ, впрочем, уже работает как сортировка по умолчанию, однако мы можем добиться таких же результатов и с помощью параметра key:
sortList = [‘a’, ‘cc’, ‘bbb’]
# Создаем «внешнюю» функцию, которая будет сортировать список в алфавитном порядке:
def sortByAlphabet(inputStr):
return inputStr[0] # Ключом является первый символ в каждой строке, сортируем по нему
# Вторая функция, сортирующая список по длине строки:
def sortByLength(inputStr):
return len(inputStr) # Ключом является длина каждой строки, сортируем по длине
print u’Исходный список: ‘, sortList # >>> [‘a’, ‘cc’, ‘bbb’]
sortList.sort(key=sortByAlphabet) # Каждый элемент массива передается в качестве параметра функции
print u’Отсортировано в алфавитном порядке: ‘, sortList # >>> [‘a’, ‘bbb’, ‘cc’]
sortList.sort(key=sortByLength) # Каждый элемент массива передается в качестве параметра функции
print u’Отсортировано по длине строки: ‘, sortList # >>> [‘a’, ‘cc’, ‘bbb’]
# Теперь отсортируем по длине строки, но в обратном порядке:
sortList.sort(key=sortByLength, reverse=True) # В обратном порядке
print u’Отсортировано по длине строки, в обратном порядке: ‘, sortList # >>> [‘bbb’, ‘cc’, ‘a’]
Обратите внимание, что метод .sort() производит действия с исходным списком, переставляя элементы внутри него самого, и НЕ возвращает отсортированную копию исходного списка. Для получения отсортированной копии нужно использовать метод sorted:
— либо такой же вариант, но с параметром key (аналогично описанному выше):
newList = sorted(sortList, key=sortByLength)
У метода .sorted() есть и другие параметры, но мне они показались не настолько запутанными для самостоятельного разбора.
Сортировка слов в тексте по алфавиту и длине в Python 3





Задание: пользователь должен ввести с клавиатуры произвольный текст, который должен сначала отсортироваться по алфавиту (каждое слово по алфавиту), а затем каждое слово должно быть остортировано по длине. Результаты должны быть выведены на экран.
Версия Python 3.5
Когда читаешь документацию или смотришь уроки по Питону, всё предельно ясно и просто. А вот когда приходит время для практических заданий, оказывается всё не так просто, как казалось ранее. По данной задаче были попытки найти простое и понятное решение в гугле по запросам «сортировка строк python», «сортировка кортежа python» (были предположения перевести слова в кортеж), «слова по алфавиту в тексте python», «отсортировать текст по алфавиту python», «сортировка по алфавиту python», «перевести строку в список» и даже «перевести список в строку». В результате моих мучений и помощи со стороны были реализованы простые решения данной задачи.
Вывод на экран введённого текста .
Для начала определим переменную, которая будет записывать и выводить затем введённый пользователем произвольный текст. Затем выведем на экран значение переменной при помощи оператора вывода print. Здесь всё просто.
text=str(input("Enter text: ")) print(text)
Сортировка символов в списке по алфавиту .
При помощи функции sorted() отсортируем по алфавиту но не каждое слово, а каждый символ. В задаче этого не было, но на всякий случай оставлю и этот вариант здесь. Чтобы функция работала, создаём новую переменную, в которую складываем все символы отдельно и затем выводим их по алфавиту.
newList = sorted(text) print(newList) #Выведется в списке отсортированный по алфавиту каждый символ в тексте
Сортировка списка из слов по алфавиту .
Преобразование строки в список слов можно выполнить при помощи функции split() по формуле (синтаксису): S(или любая другая переменная).split(символ). То есть, происходит по сути разбиение строки по определённому разделителю, в данном случае — по пробелу. Правда, по такому коду отсортируются слова по алфавиту именно в списке (с полным синтаксисом списков: квадратными скобками и заключение каждого слова в кавычки). Немного не то опять, что нам хотелось бы получить в решении задания.
n=sorted(text.split()) print(n) #Выведется в списке отсортированные по алфавиту слова, что были в ведённом пользователем тексте
Сортировка слов в строке по алфавиту .
А вот код ниже с использованием той же функции split() и цикла путём итерирования слов в тексте будут выведены на экран отсортированные по алфавиту введённые пользователем слова текста. А чтобы при итерации каждое слово не было с новой строки (как по умолчанию), дополнительно введём переменную e, с помощью которой слова будут выведены в одну строку, а не в столбик.
w=text.split() e="" for r in sorted(w): e=e+" " +r print(e) #Выведется в строке сортировка слов из введённого пользователем текста по алфавиту
Сортировка слов по длине .
Пришло время отсортировать слова в тексте по их длине. Здесь также используем split() для разделения слов в тексте. Теперь нужно отсортировать слова по длине. Для этого нужно создать анонимную функцию (содержащую лишь одно выражение определения длины слова) при помощи инструкции lambda.
l = text.split() q="" for i in sorted(l,key=lambda a: len(a)): q = q + " " + i print(q) #Выведется в строке отсортированные в порядке возрастания количества символов слова из введённого пользователем текста