Python. Сортировка по алфавиту списка словарей
Необходимо отсортировать его в алфавитном порядке средствами python по полю ‘full name’ и раскидать объекты в категории по буквам кириллического алфавита («А», «Б». «Я»). Подскажите, пожалуйста, с какой стороны подойти к решению
Отслеживать
while1pass
задан 3 мар 2016 в 11:15
while1pass while1pass
2,265 1 1 золотой знак 29 29 серебряных знаков 56 56 бронзовых знаков
json чтобы получить список, а потом его отсортировать и далее группировать
3 мар 2016 в 12:17
Раскидать по первой букве легко (особенно если отсортирован список по алфавиту), но это другой вопрос. Задайте его отдельно. Более того не обязательно сортировать, если раскидки это всё что вам нужно в итоге. Что вы хотите получить, если первая буква не из кириллицы?
4 мар 2016 в 0:24
похожий вопрос: How do I sort a list of dictionaries by values of the dictionary in Python?
4 мар 2016 в 0:31
да, ввожу в заблуждение вопросом, уже разобрался
4 мар 2016 в 8:12
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
Данные в вопросе не являются JSON объектом, например, json.loads() выкинет ошибку.
Если интерпертировать данные как исходный код Питона, тогда guys_json (вводящее в заблуждение имя) является обычным списком словарей (никакого отношения к JSON-формату, кроме того что синтаксис похож (как и задумано)).
Легко отсортировать список словарей по значению заданного поля:
list_of_dicts.sort(key=lambda d: d['full_name'])
Уже есть готовая функция, которую можно вместо lambda использовать:
from operator import itemgetter list_of_dicts.sort(key=itemgetter('full_name'))
Обе вызова сортируют, используя лексикографический порядок, что для не-ASCII символов может быть не то что нужно. См. Поиск упорядоченной подстроки в строке Python.
Сортировка слов в тексте по алфавиту и длине в 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) #Выведется в строке отсортированные в порядке возрастания количества символов слова из введённого пользователем текста
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: исчерпывающий гайд
Сортировка в Python выполняется с помощью sorted() и list.sort(). Разбираем на примерах, как это работает.
Сортировка в Python выполняется функцией sorted() , если это итерируемые объекты, и методом list.sort() , если это список. Рассмотрим подробнее, как это работало в старых версиях и как работает сейчас.
Примечание Вы читаете улучшенную версию некогда выпущенной нами статьи.
Основы сортировки
Так как отсортировать список Python? Для сортировки по возрастанию достаточно вызвать функцию сортировки Python sorted() , которая вернёт новый отсортированный список:
>>> sorted([5, 2, 3, 1, 4]) [1, 2, 3, 4, 5]
Для сортировки списка Python также можно использовать метод списков list.sort() , который изменяет исходный список (и возвращает None во избежание путаницы). Обычно Python sort list не так удобен, как использование sorted() , но если вам не нужен исходный список, то так будет немного эффективнее:
>>> a = [5, 2, 3, 1, 4] >>> a.sort() >>> a [1, 2, 3, 4, 5]
Прим.перев. В Python вернуть None и не вернуть ничего — одно и то же.
Ещё одно отличие заключается в том, что метод list.sort() определён только для списков, в то время как функция sorted Python работает со всеми итерируемыми объектами. Грубо говоря, функция sort Python сортирует список и сохраняет его в отсортированном виде, в то время как функция sorted Питон создаёт новый отсортированный список без изменения исходного.
>>> sorted() [1, 2, 3, 4, 5]
Прим.перев. При итерировании по словарю Python возвращает его ключи. Если вам нужны их значения или пары «ключ-значение», используйте методы dict.values() и dict.items() соответственно.
Рассмотрим основные функции сортировки Python.
Функции-ключи
С версии Python 2.4 у list.sort() и sorted() появился параметр key для указания функции, которая будет вызываться на каждом элементе до сравнения. Вот регистронезависимое сравнение строк:
>>> sorted("This is a test string from Andrew".split(), key=str.lower) ['a', 'Andrew', 'from', 'is', 'string', 'test', 'This']
Значение key должно быть функцией, принимающей один аргумент и возвращающей ключ для сортировки. Работает быстро, потому что функция-ключ вызывается один раз для каждого элемента.
Часто можно встретить код, где сложный объект сортируется по одному из его индексов. Например:
>>> student_tuples = [ ('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10), ] >>> sorted(student_tuples, key=lambda student: student[2]) # сортируем по возрасту [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
Тот же метод работает для объектов с именованными атрибутами:
>>> class Student: def __init__(self, name, grade, age): self.name = name self.grade = grade self.age = age def __repr__(self): return repr((self.name, self.grade, self.age)) def weighted_grade(self): return 'CBA'.index(self.grade) / self.age >>> student_objects = [ Student('john', 'A', 15), Student('jane', 'B', 12), Student('dave', 'B', 10), ] >>> sorted(student_objects, key=lambda student: student.age) # сортируем по возрасту [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
Функции модуля operator
Показанные выше примеры функций-ключей встречаются настолько часто, что Python предлагает удобные функции, чтобы сделать всё проще и быстрее. Модуль operator содержит функции itemgetter() , attrgetter() и, начиная с Python 2.6, methodcaller() . С ними всё ещё проще:
>>> from operator import itemgetter, attrgetter, methodcaller >>> sorted(student_tuples, key=itemgetter(2)) [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)] >>> sorted(student_objects, key=attrgetter('age')) [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
Функции operator дают возможность использовать множественные уровни сортировки массива Python. Отсортируем учеников сначала по оценке, а затем по возрасту:
>>> sorted(student_tuples, key=itemgetter(1, 2)) [('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)] >>> sorted(student_objects, key=attrgetter('grade', 'age')) [('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]
Используем функцию methodcaller() для сортировки учеников по взвешенной оценке:
>>> [(student.name, student.weighted_grade()) for student in student_objects] [('john', 0.13333333333333333), ('jane', 0.08333333333333333), ('dave', 0.1)] >>> sorted(student_objects, key=methodcaller('weighted_grade')) [('jane', 'B', 12), ('dave', 'B', 10), ('john', 'A', 15)]
Сортировка по возрастанию и сортировка по убыванию в Python
list.sort() и sorted() есть параметр reverse , принимающий boolean-значение. Он нужен для обозначения сортировки по убыванию. Отсортируем учеников по убыванию возраста:
>>> sorted(student_tuples, key=itemgetter(2), reverse=True) [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)] >>> sorted(student_objects, key=attrgetter('age'), reverse=True) [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
Стабильность сортировки и сложные сортировки в Python
Начиная с версии Python 2.2, сортировки гарантированно стабильны: если у нескольких записей есть одинаковые ключи, их порядок останется прежним. Пример:
>>> data = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)] >>> sorted(data, key=itemgetter(0)) [('blue', 1), ('blue', 2), ('red', 1), ('red', 2)]
Обратите внимание, что две записи с ‘blue’ сохранили начальный порядок. Это свойство позволяет составлять сложные сортировки путём постепенных сортировок. Далее мы сортируем данные учеников сначала по возрасту в порядке возрастания, а затем по оценкам в убывающем порядке, чтобы получить данные, отсортированные в первую очередь по оценке и во вторую — по возрасту:
>>> s = sorted(student_objects, key=attrgetter('age')) # сортируем по вторичному ключу >>> sorted(s, key=attrgetter('grade'), reverse=True) # по первичному [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
Алгоритмы сортировки Python вроде Timsort проводят множественные сортировки так эффективно, потому что может извлечь пользу из любого порядка, уже присутствующего в наборе данных.
Декорируем-сортируем-раздекорируем
- Сначала исходный список пополняется новыми значениями, контролирующими порядок сортировки.
- Затем новый список сортируется.
- После этого добавленные значения убираются, и в итоге остаётся отсортированный список, содержащий только исходные элементы.
Вот так можно отсортировать данные учеников по оценке:
>>> decorated = [(student.grade, i, student) for i, student in enumerate(student_objects)] >>> decorated.sort() >>> [student for grade, i, student in decorated] # раздекорируем [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
Это работает из-за того, что кортежи сравниваются лексикографически, сравниваются первые элементы, а если они совпадают, то сравниваются вторые и так далее.
Не всегда обязательно включать индекс в декорируемый список, но у него есть преимущества:
- Сортировка стабильна — если у двух элементов одинаковый ключ, то их порядок не изменится.
- У исходных элементов не обязательно должна быть возможность сравнения, так как порядок декорированных кортежей будет определяться максимум по первым двум элементам. Например, исходный список может содержать комплексные числа, которые нельзя сравнивать напрямую.
Ещё эта идиома называется преобразованием Шварца в честь Рэндела Шварца, который популяризировал её среди Perl-программистов.
Для больших списков и версий Python ниже 2.4, «декорируем-сортируем-раздекорируем» будет оптимальным способом сортировки. Для версий 2.4+ ту же функциональность предоставляют функции-ключи.
Использование параметра cmp
Все версии Python 2.x поддерживали параметр cmp для обработки пользовательских функций сравнения. В Python 3.0 от этого параметра полностью избавились. В Python 2.x в sort() можно было передать функцию, которая использовалась бы для сравнения элементов. Она должна принимать два аргумента и возвращать отрицательное значение для случая «меньше чем», положительное — для «больше чем» и ноль, если они равны:
>>> def numeric_compare(x, y): return x - y >>> sorted([5, 2, 4, 1, 3], cmp=numeric_compare) [1, 2, 3, 4, 5]
Можно сравнивать в обратном порядке:
>>> def reverse_numeric(x, y): return y - x >>> sorted([5, 2, 4, 1, 3], cmp=reverse_numeric) [5, 4, 3, 2, 1]
При портировании кода с версии 2.x на 3.x может возникнуть ситуация, когда нужно преобразовать пользовательскую функцию для сравнения в функцию-ключ. Следующая обёртка упрощает эту задачу по Python:
def cmp_to_key(mycmp): 'Перевести cmp=функция в key=функция' class K(object): def __init__(self, obj, *args): self.obj = obj def __lt__(self, other): return mycmp(self.obj, other.obj) < 0 def __gt__(self, other): return mycmp(self.obj, other.obj) >0 def __eq__(self, other): return mycmp(self.obj, other.obj) == 0 def __le__(self, other): return mycmp(self.obj, other.obj) = 0 def __ne__(self, other): return mycmp(self.obj, other.obj) != 0 return K
Чтобы произвести преобразование, оберните старую функцию:
>>> sorted([5, 2, 4, 1, 3], key=cmp_to_key(reverse_numeric)) [5, 4, 3, 2, 1]
В Python 2.7 функция cmp_to_key() была добавлена в модуль functools.
Поддержание порядка сортировки
В стандартной библиотеке Python нет модулей, аналогичных типам данных C++ вроде set и map . Python делегирует эти задачи сторонним библиотекам, доступным в Python Package Index: они используют различные методы для сохранения типов list , dict и set в отсортированном порядке. Поддержание порядка с помощью специальной структуры данных может помочь избежать очень медленного поведения (квадратичного времени выполнения) при наивном подходе с редактированием и постоянной пересортировкой данных. Вот некоторые из модулей, реализующих эти типы данных:
- SortedContainers — реализация сортированных типов list , dict и set на чистом Python, по скорости не уступает реализациям на C. Тестирование включает 100% покрытие кода и многие часы стресс-тестирования. В документации можно найти полный справочник по API, сравнение производительности и руководства по внесению своего вклада.
- rbtree — быстрая реализация на C для типов dict и set . Реализация использует структуру данных, известную как красно-чёрное дерево.
- treap — сортированный dict . В реализации используется Декартово дерево, а производительность улучшена с помощью Cython.
- bintrees — несколько реализаций типов dict и set на основе деревьев на C. Самые быстрые основаны на АВЛ и красно-чёрных деревьях. Расширяет общепринятый API для предоставления операций множеств для словарей.
- banyan — быстрая реализация dict и set на C.
- skiplistcollections — реализация на чистом Python, основанная на списках с пропусками, предлагает ограниченный API для типов dict и set .
- blist — предоставляет сортированные типы list , dict и set , основанные на типе данных «blist», реализация на Б-деревьях. Написано на Python и C.
Прочее
Для сортировки с учётом языка используйте locale.strxfrm() в качестве ключевой функции или locale.strcoll() в качестве функции сравнения. Параметр reverse всё ещё сохраняет стабильность сортировки. Этот эффект можно сымитировать без параметра, использовав встроенную функцию reversed() дважды:
>>> data = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)] >>> assert sorted(data, reverse=True) == list(reversed(sorted(reversed(data))))
Чтобы создать стандартный порядок сортировки для класса, просто добавьте реализацию соответствующих методов сравнения:
>>> Student.__eq__ = lambda self, other: self.age == other.age >>> Student.__ne__ = lambda self, other: self.age != other.age >>> Student.__lt__ = lambda self, other: self.age < other.age >>> Student.__le__ = lambda self, other: self.age >> Student.__gt__ = lambda self, other: self.age > other.age >>> Student.__ge__ = lambda self, other: self.age >= other.age >>> sorted(student_objects) [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
Для типов, сравнение которых работает обычным образом, рекомендуется определять все 6 операторов. Декоратор классов functools.total_ordering упрощает их реализацию. Функциям-ключам не нужен доступ к внутренним данным сортируемых объектов. Они также могут осуществлять доступ к внешним ресурсам. Например, если оценки ученика хранятся в словаре, их можно использовать для сортировки отдельного списка с именами учеников:
>>> students = ['dave', 'john', 'jane'] >>> newgrades = >>> sorted(students, key=newgrades.__getitem__) ['jane', 'dave', 'john']
Надеемся, теория по Python list sort и соответствующие задачи по Питону с разбором были для вас полезны. Вас также может заинтересовать статьи:
- Хочу научиться программировать на Python. С чего начать?
- Хочу научиться программировать на Python: инструкция для продолжающих