Форум сайта python.su
Приветствую!
Посмотрел несколько тем в разделе - судя по всему, даже новичком себя могу назвать только с натяжкой))
Прохожу сейчас один курс по Python, в одной из задач (не уверен, что ссылку можно выкладывать) требовалось считать из файла данные о болезнях по годам и написать функцию, которая будет формировать список словарей {Название болезни: кол-во}, {Название болезни: кол-во} …, но при этом данные в списке должны быть отсортированы по количеству. Долго возился, в результате решил через сбор данных сначала во вспомогательный список {“Болезнь”: название болезни, “Кол-во”: кол-во}, …, потом уже данные из этого списка сортировал и помещал в конечный.
Вопрос такой: можно ли было как-то организовать сортировку самого этого списка напрямую через sort и значения в словарях, если в каждом словаре по одной записи, но ключи этих записей везде разные?
P.S. И заодно немного не в тему: правильно ли я понимаю, что регистрация с почтой outlook на форуме недоступна? Регистрировался еще утром, письмо до сих пор не пришло, днем написал по этому поводу с того же адреса в поддержку - тоже тишина.
P.P.S. После правки сообщения структуры списков в квадратных скобках почему-то перестали отображаться, оставил просто словари в фигурных
Отредактировано Egorro13 (Апрель 17, 2019 00:28:57)
Офлайн
Egorro13Надо выложить задание, не надо перессказывать его.
в одной из задач (не уверен, что ссылку можно выкладывать)
Офлайн
py.user.nextЗадание 8.2.8
Надо выложить задание, не надо перессказывать его.
# Формирование списков data_year_2_sorted_adult = [] data_year_2_sorted_children = [] data_changes_sorted_adult = [] data_changes_sorted_children = [] tmp = [] for rec in data: d_class = rec[0] value1 = rec[i_year1] value2 = rec[i_year2] d_change = (value2 - value1) / value1 * 100 record = dict(theclass=d_class, value=value2, change=d_change, age=rec[-1]) tmp.append(record) for rec in sorted(tmp, key=lambda d: d['value'], reverse=True): record = {rec['theclass']: round(rec['value'], ndigits=2)} if rec['age'] == ADULTS: data_year_2_sorted_adult.append(record) elif rec['age'] == CHILDREN: data_year_2_sorted_children.append(record) else: raise NoSuchYearError("Неверный возраст!") for rec in sorted(tmp, key=lambda d: d['change'], reverse=True): record = {rec['theclass']: round(rec['change'], ndigits=2)} if rec['age'] == ADULTS: data_changes_sorted_adult.append(record) elif rec['age'] == CHILDREN: data_changes_sorted_children.append(record) else: raise NoSuchYearError("Неверный возраст!")
Отредактировано Egorro13 (Апрель 17, 2019 09:22:15)
Офлайн
Упорядоченный словарь сделать можно через OrderedDict()
>>> import json >>> import collections >>> >>> d = collections.OrderedDict() >>> d['c'] = 3 >>> d['b'] = 2 >>> d['a'] = 1 >>> >>> json.dumps(d) '{"c": 3, "b": 2, "a": 1}' >>>
>>> dct = {'x' : [{'a': 4}, ... {'b': 3}, ... {'c': 2}, ... {'d': 1}]} >>> >>> >>> dct {'x': [{'a': 4}, {'b': 3}, {'c': 2}, {'d': 1}]} >>> >>> dct['x'].sort(key=lambda d: tuple(d.values())[0]) >>> dct {'x': [{'d': 1}, {'c': 2}, {'b': 3}, {'a': 4}]} >>>
Офлайн
Спасибо, насчет сортировки словарей в заголовке - неправильно выразился: уже несколько раз сталкивался с необходимостью сортировать содержимое именно словарей, но так и не разобрался до конца, потому, видимо, и тут на автомате сработало))
Насчет tuple(d.values()) в голову не пришло - на Питон перешел с Явы, еще эти кортежи и структуры в голове не утрамбовались, еще раз благодарю!
Офлайн
Egorro13Словари не имеют порядка, так как основное их предазначение - быстрый доступ вне зависимости от количества элементов в словаре. То есть хоть при десяти элементах, хоть при миллионе элементов, доступ к каждому элементу должен происходить мнгновенно, без перебора всех элементов. Вот из-за этого там нет порядка. Хотя сейчас словари в питоне сделали упорядоченными (по времени добавления элементов в словарь), не нарушив главного свойства - быстрого поиска элемента в словаре при любом их количестве.
уже несколько раз сталкивался с необходимостью сортировать содержимое именно словарей, но так и не разобрался до конца
>>> d = {'a': 4, 'b': 3, 'c': 2, 'd': 1} >>> >>> out = dict(sorted(d.items(), key=lambda i: i[1])) >>> out {'d': 1, 'c': 2, 'b': 3, 'a': 4} >>> >>> for i, j in zip(d, out): ... print('d:', i, '->', d[i], 'out:', j, '->', out[j]) ... d: a -> 4 out: d -> 1 d: b -> 3 out: c -> 2 d: c -> 2 out: b -> 3 d: d -> 1 out: a -> 4 >>>
Офлайн
py.user.nextДа, спасибо, это я вроде более-менее понимаю, хотя успешно сортировать до сих пор получалось (насколько помню) только через sorted(dict.keys()), а уже по отсортированным в нужном порядке ключам получать и значения. Сортировать именно по элементам еще толком не научился - опять же, из-за переучивания не все вещи легко даются.
Словари не имеют порядка, так как основное их предазначение - быстрый доступ вне зависимости от количества элементов в словаре. То есть хоть при десяти элементах, хоть при миллионе элементов, доступ к каждому элементу должен происходить мнгновенно, без перебора всех элементов. Вот из-за этого там нет порядка. Хотя сейчас словари в питоне сделали упорядоченными (по времени добавления элементов в словарь), не нарушив главного свойства - быстрого поиска элемента в словаре при любом их количестве.
Сортировка словаря сейчас выглядит как взятие словаря, взятие всех пар словаря, сортировка пар и создание нового словаря из отсортированных пар. Даже на встроенных словарях это работает.
Офлайн
Egorro13Словарь в питоне - это нагруженное множество. Нагруженное множество - это динамическая структура данных. То есть это простое множество (динамическая структура), где у каждого элемента есть нагрузка. Соответственно, к словарю применяется тот же метод поиска, что и для множества. Строится бинарное дерево и по нему идёт поиск. Для миллиона элементов поиск займёт log2(1000000) = 20 переходов по элементам, а для миллиарда элементов поиск займёт log2(1000000000) = 30 переходов по элементам. Поэтому поиск в словаре равен O(1) - с одинаковой скоростью находишь любой элемент, несмотря на их количество. Конечно, это не точная оценка, а приблизительная. Но для 10, 100, 1000, 1000000, 1000000000 элементов скорость поиска будет похожа на одну и ту же.
Что в упор не понимаю - каким образом может осуществляться мгновенный доступ к элементам словарей
Отредактировано py.user.next (Апрель 18, 2019 05:18:08)
Офлайн
py.user.nextБлагодарю, теперь вроде что-то складывается в голове, всплывает что-то еще из 90-х, когда первые подходы к программированию пытался делать))
Строится бинарное дерево и по нему идёт поиск. Для миллиона элементов поиск займёт log2(1000000) = 20 переходов по элементам, а для миллиарда элементов поиск займёт log2(1000000000) = 30 переходов по элементам. Поэтому поиск в словаре равен O(1) - с одинаковой скоростью находишь любой элемент, несмотря на их количество
Офлайн