[ Сборник задач ]
Тема 5. Работа со словарями

[ Сборник задач ]
Тема 5. Работа со словарями

Python Workbook Cover T1
  • Тип данных: dict
  • Контент: Вопросы (6шт) + задачи (5шт)

Оглавление

1
Введение
Рассмотрим особенности словарей в Python, операции над ними; дополнительные структуры данных, образованные от них; темы, необходимые для решения заданий.
Перейти
2
Вопросы и ответы
6 вопросов по теме "Словари" + ответы
Перейти
3
Условия задач
5 задач по теме двух уровней сложности: Базовый и *Продвинутый
Перейти
4
Решения задач
Приводим код решений указанных выше задач
Перейти
1
One

Введение

Словари (dict) в языке Python – наиболее распространенный тип данных. Они буквально везде (в классах, модулях, функциях), поэтому сделаны максимально эффективными.

Для решения заданий необходимо повторить: свойства, стандартные операции со словарями, как их создавать, каковы требования к ключам и значениям, как копировать, обновлять, распаковывать, какими способами можно просматривать содержимое.

Для углубленного погружения в тему следует ознакомиться с типами defaultdict, OrderedDict, Counter, ChainMap, UserDict из встроенного модуля collections. В некоторых случаях они могут пригодиться, существенно сократив длину кода.

Читайте также

2
Two

Вопросы по теме "Работа со словарями"

3
Three

Задачи по теме "Работа со словарями"

Задача 1
Напишите функцию to_dict(lst), которая принимает аргумент в виде списка и возвращает словарь, в котором каждый элемент списка является и ключом и значением. Предполагается, что элементы списка будут соответствовать правилам задания ключей в словарях.
Задача 2
Иван решил создать самый большой словарь в мире. Для этого он придумал функцию biggest_dict(**kwargs), которая принимает неограниченное количество параметров «ключ: значение» и обновляет созданный им словарь my_dict, состоящий всего из одного элемента «first_one» со значением «we can do it». Воссоздайте эту функцию.
Задача 3
Дана строка в виде случайной последовательности чисел от 0 до 9.

Требуется создать словарь, который в качестве ключей будет принимать данные числа (т. е. ключи будут типом int), а в качестве значений – количество этих чисел в имеющейся последовательности. Для построения словаря создайте функцию count_it(sequence), принимающую строку из цифр. Функция должна возвратить словарь из 3-х самых часто встречаемых чисел.
Задача 4
Создайте словарь с количеством элементов не менее 5-ти. Поменяйте местами первый и последний элемент объекта. Удалите второй элемент. Добавьте в конец ключ «new_key» со значением «new_value». Выведите на печать итоговый словарь. Важно, чтобы словарь остался тем же (имел тот же адрес в памяти).
* Задача 5
Имеется ряд словарей с пересекающимися ключами (значения - положительные числа). Напишите 2 функции, которые делают с массивом словарей следующие операции:
1-ая функция max_dct(*dicts) формирует новый словарь по правилу:

Если в исходных словарях есть повторяющиеся ключи, выбираем среди их значений максимальное и присваиваем этому ключу (например, в словаре_1 есть ключ "а" со значением 5, и в словаре_2 есть ключ "а", но со значением 9. Выбираем максимальное значение, т. е. 9, и присваиваем ключу "а" в уже новом словаре).

Если ключ не повторяется, то он просто переносится со своим значением в новый словарь (например, ключ "с" встретился только у одного словаря, а у других его нет. Следовательно, переносим в новый словарь этот ключ вместе с его значением). Сформированный словарь возвращаем.

2-ая функция sum_dct(*dicts) суммирует значения повторяющихся ключей. Значения остальных ключей остаются исходными. (Проводятся операции по аналогу первой функции, но берутся не максимумы, а суммы значений одноименных ключей). Функция возвращает сформированный словарь.
4
Two

Решения

Задача 1. Базовый уровень

Условие

Напишите функцию to_dict(lst), которая принимает аргумент в виде списка и возвращает словарь, в котором каждый элемент списка является и ключом и значением. Предполагается, что элементы списка будут соответствовать правилам задания ключей в словарях. 
Для решения воспользуемся генератором словарей (dict comprehension).
Решение – IDE

def to_dict(lst):
    return {element: element for element in lst}

# Тесты
print(to_dict([1, 2, 3, 4]))
print(to_dict(['grey', (2, 17), 3.11, -4]))
Результат выполнения

{1: 1, 2: 2, 3: 3, 4: 4}
{'grey': 'grey', (2, 17): (2, 17), 3.11: 3.11, -4: -4}

Читайте также

Задача 2. Базовый уровень

Условие

Иван решил создать самый большой словарь в мире. Для этого он придумал функцию biggest_dict(**kwargs), которая принимает неограниченное количество параметров «ключ: значение» и обновляет созданный им словарь my_dict, состоящий всего из одного элемента «first_one» со значением «we can do it». Воссоздайте эту функцию. 
При решении следует учесть, что словарь – изменяемый объект. Поэтому функция должна его дополнять и ничего не возвращать.
Решение - IDE

my_dict = {'first_one': 'we can do it'}


def biggest_dict(**kwargs):
    my_dict.update(**kwargs)


biggest_dict(k1=22, k2=31, k3=11, k4=91)
biggest_dict(name='Елена', age=31, weight=61, eyes_color='grey')
print(my_dict)
Результат выполнения

{'first_one': 'we can do it', 'k1': 22, 'k2': 31, 'k3': 11, 'k4': 91, 'name': 'Елена', 'age': 31, 'weight': 61, 'eyes_color': 'grey'}

Задача 3. Базовый уровень

Условие

Дана строка в виде случайной последовательности чисел от 0 до 9. 

Требуется создать словарь, который в качестве ключей будет принимать данные числа (т. е. ключи будут типом int), а в качестве значений – количество этих чисел в имеющейся последовательности. Для построения словаря создайте функцию count_it(sequence), принимающую строку из цифр. Функция должна возвратить словарь из 3-х самых часто встречаемых чисел.
Более очевидный способ: без использования дополнительных модулей.
Решение – IDE

def count_it(sequence):
    # При помощи генератора создаем словарь, где ключом выступает уникальный элемент строки, а значением - его частота (вычисляется методом count()) 	
    num_frequency = {int(item): sequence.count(item) for item in sequence}

    # Сортируем словарь по значениям в порядке возрастания. Для этого методом items() формируем пары “(ключ, значение)” в виде кортежей по всем элементам словаря. Т. к. нужно сортировать по значениям, берем второй элемент кортежей. В результате получим список из кортежей “(ключ, значение)”
    sorted_num_frequency = sorted(num_frequency.items(), key=lambda element: element[1])

    # Возвращаем последние 3 элемента списка, т. е. кортежи с самыми большими значениями второй компоненты, которые преобразовываем в словарь 
    return dict(sorted_num_frequency[-3:])

# Тесты
print(count_it('1111111111222'))
print(count_it('123456789012133288776655353535353441111'))
print(count_it('007767757744331166554444'))
Результат выполнения

{1: 10, 2: 3}
{3: 8, 1: 7, 5: 7}
{7: 6, 4: 6, 6: 3}
Второй способ предполагает применение Counter из модуля collections.
Решение – IDE

from collections import Counter


def count_it(sequence):
    return dict(Counter([int(num) for num in sequence]).most_common(3))

# Тесты
print(count_it('1111111111222'))
print(count_it('123456789012133288776655353535353441111'))
print(count_it('007767757744331166554444'))

Результат выполнения

{1: 10, 2: 3}
{3: 8, 1: 7, 5: 7}
{7: 6, 4: 6, 6: 3}

Задача 4. Базовый уровень

Условие

Создайте словарь с количеством элементов не менее 5-ти. Поменяйте местами первый и последний элемент объекта. Удалите второй элемент. Добавьте в конец ключ «new_key» со значением «new_value». Выведите на печать итоговый словарь. Важно, чтобы словарь остался тем же (имел тот же адрес в памяти).
Для одного из вариантов решения потребуется воспользоваться методами keys(), values(), чтобы получить контейнеры с ключами и значениями. Так как напрямую с ними работать нельзя, преобразуем их в списки, с которыми проведем требуемые операции. Очистим изначальный словарь и обновим его новыми значениями из списков. А в конце добавим новый элемент ('new_key': 'new_value') к словарю. Остался тот же словарь, но с требуемыми преобразованиями.
Решение - Интерактивный режим

>>> from collections import OrderedDict
>>> dct = OrderedDict({1: 1, 2: 2, 3: 3, 4: 4, 5: 5})

# Меняем местами первый и последний элементы
>>> first = list(dct.items())[0]
>>> last = list(dct.items())[-1]
>>> dct.move_to_end(key=first[0])
>>> dct.move_to_end(key=last[0], last=False)

# Удаляем второй элемент
>>> second = list(dct.items())[1]
>>> del dct[second[0]]

# Вставляем новый элемент
>>> dct['new_key'] = 'new_value'
>>> my_dict
{5: 5, 3: 3, 4: 4, 1: 1, 'new_key': 'new_value'}
>>> id(my_dict)
17128656
>>> start_dict_id
17128656

Задача 5. * Продвинутый уровень

Условие

Имеется ряд словарей с пересекающимися ключами (значения - положительные числа). Напишите 2 функции, которые делают с массивом словарей следующие операции:
1-ая функция max_dct(*dicts) формирует новый словарь по правилу:

Если в исходных словарях есть повторяющиеся ключи, выбираем среди их значений максимальное и присваиваем этому ключу (например, в словаре_1 есть ключ “а” со значением 5, и в словаре_2 есть ключ “а”, но со значением 9. Выбираем максимальное значение, т. е. 9, и присваиваем ключу “а” в уже новом словаре).  

Если ключ не повторяется, то он просто переносится со своим значением в новый словарь (например, ключ “с” встретился только у одного словаря, а у других его нет. Следовательно, переносим в новый словарь этот ключ вместе с его значением). Сформированный словарь возвращаем.

2-ая функция sum_dct(*dicts) суммирует значения повторяющихся ключей. Значения остальных ключей остаются исходными. (Проводятся операции по аналогу первой функции, но берутся не максимумы, а суммы значений одноименных ключей). Функция возвращает сформированный словарь.

Для проверки работоспособности создадим 4 словаря. Чтобы максимально упростить решение и сделать его «питоничным», воспользуемся модулем collections и его классом Counter, а также функцией reduce из модуля functools.
Решение - IDE

from collections import Counter
from functools import reduce
dict_1 = {1: 12, 2: 33, 3: 10, 4: 10, 5: 2, 6: 90}
dict_2 = {1: 12, 3: 7, 4: 1, 5: 2, 7: 112}
dict_3 = {2: 3, 3: 3, 4: 60, 6: 8, 7: 25, 8: 71}
dict_4 = {3: 1, 4: 13, 5: 31, 9: 9, 10: 556}


def sum_dct(*dicts):
    return dict(reduce(lambda a, b: Counter(a) + Counter(b), dicts))

def max_dct(*dicts):
    return dict(reduce(lambda a, b: Counter(a) | Counter(b), dicts))

# Тесты
print(max_dct(dict_1, dict_2))
print(sum_dct(dict_1, dict_4, dict_3))
print(max_dct(dict_1, dict_2, dict_3, dict_4))
print(sum_dct(dict_1, dict_2, dict_3, dict_4))
Результат выполнения

{1: 12, 2: 33, 3: 10, 4: 10, 5: 2, 6: 90, 7: 112}
{1: 12, 2: 36, 3: 14, 4: 83, 5: 33, 6: 98, 9: 9, 10: 556, 7: 25, 8: 71}
{1: 12, 2: 33, 3: 10, 4: 60, 5: 31, 6: 90, 7: 112, 8: 71, 9: 9, 10: 556}
{1: 24, 2: 36, 3: 21, 4: 84, 5: 35, 6: 98, 7: 137, 8: 71, 9: 9, 10: 556}

Так как функции отличаются только операцией, а весь код повторяется, их можно упростить за счет модуля operator и дополнительной функции-обработчика dict_transformer().
Решение - IDE

from collections import Counter
from functools import reduce
from operator import or_, add

def sum_dct(*dicts):
    return dict_transformer(*dicts)

def max_dct(*dicts):
    return dict_transformer(*dicts, op=or_)

def dict_transformer(*dicts, op=add):
    return dict(reduce(lambda a, b: op(Counter(a), Counter(b)), dicts))


# Тесты
print(max_dct(dict_1, dict_2))  # Ищем максимум
print(sum_dct(dict_1, dict_4, dict_3))  # Складываем 
print(max_dct(dict_1, dict_2, dict_3, dict_4))  # Ищем максимум
print(sum_dct(dict_1, dict_2, dict_3, dict_4))  # Складываем
Результат выполнения

{1: 12, 2: 33, 3: 10, 4: 60, 5: 2, 6: 90, 7: 25, 8: 71}
{1: 12, 2: 36, 3: 14, 4: 83, 5: 33, 6: 98, 9: 9, 10: 556, 7: 25, 8: 71}
{1: 12, 2: 33, 3: 10, 4: 60, 5: 31, 6: 90, 7: 112, 8: 71, 9: 9, 10: 556}
{1: 24, 2: 36, 3: 21, 4: 84, 5: 35, 6: 98, 7: 137, 8: 71, 9: 9, 10: 556}
Как вам материал?

Читайте также