Наталья Кайда 29 ноября 2022

🐍 Самоучитель по Python для начинающих. Часть 6: Методы работы со словарями и генераторами словарей

Расскажем об особенностях словарей и генераторов словарей – минимум теории, максимум примеров плюс 10 задач для тренировки в конце статьи.
🐍 Самоучитель по Python для начинающих. Часть 6: Методы работы со словарями и генераторами словарей

Словарь dict – структура данных, в которой информация хранится в виде хеш-таблицы (ассоциативного массива). В таком массиве каждый ключ сопоставлен с определенным значением:

        my_dict = {'цвет': 'красный', 'размер': 'XS', 'цена': 650}
    

Питоновский словарь аналогичен HashMap в Java и Object в JavaScript.

Как создать словарь в Python: 6 способов

Пустой словарь создается с помощью фигурных скобок или функции dict():

        info_dict = {}
my_dict = dict()
    

Словари с данными, как и в случае со списками, можно создавать несколькими способами.

Способ 1: Перечисление ключей и значений

Данные словаря перечисляются в виде пар ключ: значение через запятую и заключаются в фигурные скобки:

        car = {'модель': 'Audi A5 Sportback', 'цвет': 'красный', 'пробег': '100500 км'}
    

Способ 2: Создание словаря с помощью dict()

При использовании этого метода ключи и значения тоже придется определить вручную:

        >>> my_dict = dict(name = 'Евгений', age = 28, position = 'Java-разработчик')
>>> print(my_dict)
{'name': 'Евгений', 'age': 28, 'position': 'Java-разработчик'}

    

Способ 3: Создание словаря с помощью zip() и dict()

Если есть два списка, в одном из которых хранятся ключи, а в другом – значения, словарь можно создать при помощи zip() и dict():

        >>> keys = ['цвет', 'размер', 'количество', 'цена']
>>> values = ['синий', '35х45х60', 5, 2500]
>>> info = dict(zip(keys, values))
>>> print(info)
{'цвет': 'синий', 'размер': '35х45х60', 'количество': 5, 'цена': 2500}

    

Способ 4: Создание словаря из списка кортежей и кортежа списков

Если имеется список кортежей, в которых первый элемент служит ключом, а второй – значением, словарь можно сформировать с помощью dict():

        >>> item = [('модель', 'Aura'), ('цвет', 'пурпурный'), ('наличие', 'на складе')]
>>> item_dict = dict(item)
>>> print(item_dict)
{'модель': 'Aura', 'цвет': 'пурпурный', 'наличие': 'на складе'}

    

Точно так же этот подход работает с кортежeм списков:

        >>> employee= (['имя', 'Никита'], ['отчество', 'Сергеевич'], ['фамилия', 'Колобков'], ['возраст', 32])
>>> empl_dict = dict(employee)
>>> print(empl_dict)
{'имя': 'Никита', 'отчество': 'Сергеевич', 'фамилия': 'Колобков', 'возраст': 32}

    

Способ 5: Метод fromkeys()

Если нужно создать словарь, у всех ключей которого – одинаковые значения, можно воспользоваться методом fromkeys():

        >>> new_dict = dict.fromkeys(['север', 'юг', 'восток', 'запад'], 0)
>>> print(new_dict)
{'север': 0, 'юг': 0, 'восток': 0, 'запад': 0}

    

Способ 6: Использование генератора словарей

Словари можно создавать на основе списков и строк. При этом одновременно можно проводить различные действия с числами и символами – математические операции, подсчет, сравнение и так далее:

        >>> numbers = [2, 18, 5, 7, 2, 32, 6, 9, 4, 8, 9, 12, 14, 14]
>>> my_dict = {n: numbers.count(n) for n in numbers}
>>> print(my_dict)
{2: 2, 18: 1, 5: 1, 7: 1, 32: 1, 6: 1, 9: 2, 4: 1, 8: 1, 12: 1, 14: 2}

    

В генераторах можно использовать преобразование типов данных и условия:

        >>> st = '12 31 4 53 6 7 4 90 8 7 56 3 42'
>>> my_dict = {n: int(n) * 2 for n in st.split() if int(n) % 2 == 0}
>>> print(my_dict)
{'12': 24, '4': 8, '6': 12, '90': 180, '8': 16, '56': 112, '42': 84}

    
Больше полезных материалов вы найдете на нашем телеграм-канале «Библиотека питониста»

Особенности словарей

Начиная с Python 3.6, словари являются упорядоченными коллекциями – пары ключ: значение хранятся в словаре в порядке добавления. В отличие от строк и списков, словари не поддерживают срезы и конкатенацию, а к элементу словаря нельзя обратиться по индексу – в качестве индексов в словарях выступают ключи:

        >>> my_dict = {'фрукт': 'яблоко', 'цвет': 'красный', 'количество': '53 кг'}
>>> print(my_dict['цвет'], my_dict[' количество '])
красный 53 кг

    

Ключи в словаре не должны повторяться – если добавить в словарь ключ, идентичный существующему, Python сохранит только один ключ с последним значением:

        >>> my_dict = {'цвет': 'красный', 'цвет': 'синий'}
>>> print(my_dict)
{'цвет': 'синий'}

    

В качестве ключей можно использовать все типы данных, которые относятся к неизменяемым: int, float, Boolean (True/False), frozenset, строки, кортежи. Нельзя использовать списки, обычные множества set и словари, поскольку они являются изменяемыми. При этом в качестве значения в словарях можно использовать данные любого типа, включая словари – такие словари называются вложенными:

        >>> hr_info = {'сотрудник1': {'имя': 'Егор', 'должность': 'пентестер'},
    	'сотрудник2': {'имя': 'Михаил', 'должность': 'DevOps'},
	    'сотрудник3': {'имя': 'Татьяна', 'должность': 'фронтендер'}}
>>> print(hr_info['сотрудник2']['должность'])
DevOps

    

Методы словарей в Python 3

Словари поддерживают некоторые методы, общие с другими типами данных, и имеют несколько своих собственных. Рассмотрим общие и уникальные методы на примерах.

Длина словаря и принадлежность элемента:

        >>> my_dict = {'товар': 'футболка', 'размер': 'XL', 'цвет': 'белый', 'количество': '560'}
>>> print(len(my_dict))
4
>>> print('есть на складе' if 'футболка' in my_dict else 'нет в наличии')
нет в наличии

    

Сумма ключей, максимальный и минимальный элементы

Функция sum() подсчитывает сумму ключей словаря и работает только в том случае, когда ключи являются числами:

        >>> my_dict = {5: '50', 8: '90'}
>>> print(sum(my_dict))
13

    

Функции min() и max() работают для большинства типов данных:

        >>> my_dict = {'напиток': 'яблочный сок', 'объем': '2 л', 'цена': 250, 'количество': '156'}
>>> print(min(my_dict), max(my_dict))
количество цена
>>> print(min(my_dict, key=len))
цена

    

Объединение словарей

Словари можно объединять – если в них есть одинаковые ключи, в полученном словаре значение будет взято из последнего словаря:

        >>> my_dict1 = {'товар': 'куртка', 'размер': 'XL', 'цвет': 'черный'}
>>> my_dict2 = {'артикул': '35m', 'количество': 34, 'цвет': 'синий'}
>>> print({**my_dict1, **my_dict2})
{'товар': 'куртка', 'размер': 'XL', 'цвет': 'синий', 'артикул': '35m', 'количество': 34}

    

Сравнение словарей

Словари считаются одинаковыми, если в них совпадают и ключи, и значения:

        >>> my_dict = {'марка': 'BMW', 'цвет': 'черный', 'автопилот': 'нет'}
>>> my_dict2 = {'марка': 'Audi', 'цвет': 'черный', 'автопилот': 'нет'}
>>> print(my_dict == my_dict2)
False

    

Получение ключей, значений и элементов

Для работы с ключами используется метод keys(), со значениями – values(), с парами – items():

        >>> my_dict = {'напиток': 'чай', 'вес': 100, 'цена': 550, 'количество': 256}
>>> print(my_dict.values())
dict_values(['чай', 100, 550, 256])
>>> print(my_dict.keys())
dict_keys(['напиток', 'вес', 'цена', 'количество'])
>>> print(my_dict.items())
dict_items([('напиток', 'чай'), ('вес', 100), ('цена', 550), ('количество', 256)])

    

Добавление и изменение элементов

Для изменения значения какого-либо ключа используют оператор присваивания = :

        >>> my_dict = {'должность': 'разработчик', 'имя': 'Антон'}
>>> my_dict['имя'] = 'Евгений'
>>> print(my_dict)
{'должность': 'разработчик', 'имя': 'Евгений'}

    

Если же такого ключа в словаре еще нет, новый элемент будет добавлен автоматически:

        >>> my_dict = {'должность': 'разработчик', 'имя': 'Евгений'}
>>> my_dict['фамилия'] = 'Егоров'
>>> print(my_dict)
{'должность': 'разработчик', 'имя': 'Евгений', 'фамилия': 'Егоров'}

    

Однако если обратиться к несуществующему элементу без присвоения ему значения, произойдет ошибка:

        >>> my_dict = {'должность': 'разработчик', 'имя': 'Евгений', 'фамилия': 'Егоров'}
>>> print(my_dict['город'])
Traceback (most recent call last):
  File "<pyshell>", line 1, in <module>
KeyError: 'город'

    

Получение значения по ключу – get()

Чтобы избежать появления показанной выше ошибки, используют метод get(), которому можно передать значение по умолчанию – оно выведется, если такого ключа в словаре нет:

        >>> my_dict = {'должность': 'инженер', 'имя': 'Кирилл'}
>>> print(my_dict.get('зарплата', 'не указана'))
не указана

    

Получение значения и/или добавление элемента с setdefault()

Другой метод для получения значения – setdefault(). Он действует двумя разными способами:

1) Если указанный ключ уже есть в словаре – возвращает его значение (даже при наличии значения по умолчанию):

        >>> my_dict = {'возраст': 25, 'имя': 'Роман'}
>>> print(my_dict.setdefault('возраст', 'не указан'))
25

    

2) Если ключа нет – вставляет элемент в словарь, возвращает значение:

        >>> my_dict = {'возраст': 35, 'имя': 'Егор'}
>>> print(my_dict.setdefault('зарплата', 150000))
150000
>>> print(my_dict)
{'возраст': 35, 'имя': 'Егор', 'зарплата': 150000}

    

Дополнение словаря

Элементы одного словаря можно «обновить», дополнить элементами другого. В случае совпадения ключей, как и при показанном ранее объединении словарей, сохраняются значения второго словаря:

        >>> my_dict1 = {'должность': 'инженер', 'имя': 'Роман'}
>>> my_dict2 = {'должность': 'врач', 'имя': 'Роман'}
>>> my_dict1.update(my_dict2)
>>> print(my_dict1)
{'должность': 'врач', 'имя': 'Роман'}

    

Удаление элементов словаря

Как и в случае со списками, удалять элементы из словарей можно несколькими способами:

del – удаляет элемент с заданным ключом:

        >>> my_dict = {'жанр': 'триллер', 'рейтинг': 7.5, 'название': 'Опасные связи'}
>>> del my_dict['название']
>>> print(my_dict)
{'жанр': 'триллер', 'рейтинг': 7.5}

    

pop() – возвращает удаленное значение:

        >>> my_dict = {'жанр': 'драма', 'рейтинг': 8.5, 'название': 'Зеленая миля'}
>>> фильм = my_dict.pop('название')
>>> print(фильм)
Зеленая миля

    

popitem() – удаляет последний добавленный элемент и возвращает его ключ: значение в виде кортежа:

        >>> my_dict = {'жанр': 'фэнтези', 'рейтинг': 7.7, 'название': 'Властелин колец'}
>>> movie = my_dict.popitem()
>>> print(movie)
('название', 'Властелин колец')

    

clear() – удаляет все элементы словаря:

        >>> my_dict = {'жанр': 'драма', 'рейтинг': 6.1, 'название': 'В сердце моря'}
>>> my_dict.clear()
>>> print(my_dict)
{}

    

Создание копии словаря

Копия словаря создается тем же методом, что и в случае со списками – с помощью copy():

        >>> my_dict = {'жанр': 'фантастика', 'рейтинг': 8.8, 'название': 'Бегущий по лезвию бритвы'}
>>> new_dict = my_dict.copy()
>>> print(new_dict)
{'жанр': 'фантастика', 'рейтинг': 8.8, 'название': 'Бегущий по лезвию бритвы'}

    

Практика

Задание 1

Напишите программу, которая получает на вход две строки, и формирует из них словарь. Ключами служат слова из первой строки, значениями – целые числа из второй.

Пример ввода:

        яблоки сливы груши персики манго киви апельсины
34 56 23 89 55 32 11

    

Вывод:

        {'яблоки': 34, 'сливы': 56, 'груши': 23, 'персики': 89, 'манго': 55, 'киви': 32, 'апельсины': 11}
    

Решение:

        keys = input().split()
values = map(int, input().split())
my_dict = dict(zip(keys, values))
print(my_dict)

    

Задание 2

Напишите программу, которая получает на вход строку чисел, разделенных пробелами, и формирует словарь, в котором ключами служат четные числа, а значениями – слово четное.

Пример ввода:

        45 6 8 23 21 87 65 45 38
    

Вывод:

        {6: 'четное', 8: 'четное', 38: 'четное'}
    

Решение:

        nums = map(int, input().split())
my_dict = {n: 'четное' for n in nums if n % 2 == 0}
print(my_dict)

    

Задание 3

Напишите программу, которая получает на вход строку и подсчитывает, сколько раз в ней встречается каждый символ (независимо от регистра). Результат нужно вывести без фигурных скобок.

Пример ввода:

        Есть только один способ избежать критики: ничего не делайте, ничего не говорите и будьте никем.
    

Вывод:

        е-11 с-3 т-7 ь-4  -14 о-9 л-2 к-4 д-3 и-10 н-6 п-1 б-3 з-1 ж-1 а-2 р-2 :-1 ч-2 г-3 й-1 ,-1 в-1 у-1 м-1 .-1
    

Решение:

        st = input().lower()
my_dict = {i: st.count(i) for i in st}
print(*[str(k) + '-' + str(v) for k, v in my_dict.items()])

    

Задание 4

Напишите программу, которая получает 2 слова на разных строках и определяет, являются ли эти слова анаграммами.

Пример ввода 1:

        меч
мяч

    

Вывод:

        Нет
    

Пример ввода 2:

        Минотавр
Норматив

    

Вывод:

        Да
    

Решение:

        word1, word2 = input().lower(), input().lower()
c = {k: word1.count(k) for k in word1}
d = {k: word2.count(k) for k in word2}
print ('Да' if c == d else 'Нет')

    

Задание 5

Напишите программу, которая получает строку текста и формирует из нее сначала список списков, а затем словарь, в котором первый элемент подсписка служит значением, а второй – ключом. Результат нужно вывести в столбик, без фигурных скобок.

Пример ввода:

        красный, цвет; Gucci, бренд; 145000, цена; 3, количество
    

Вывод:

        цвет: красный
бренд: Gucci
цена: 145000
количество: 3

    

Решение:

        sp = [[i.split(', ')[0], i.split(',')[1]] for i in input().split('; ')]
my_dict = {k: v for v, k in sp}
result = '\n'.join(f'{k}: {v}' for k, v in my_dict.items())
print(result)

    

Задание 6

Напишите программу, которая формирует телефонный справочник из введенной пользователем строки, а затем выдает нужный номер по имени абонента. Если абонента с таким именем нет, нужно вывести Нет такого абонента.

Пример ввода:

        Маша (923)567-78-90; Саша (912)345-23-21; Егор (812)456-64-23
Маша

    

Вывод:

        (923)567-78-90
    

Решение:

        st = input().split('; ')
phones = {i.split()[0]:i.split()[1] for i in st}
name = input()
print(phones.get(name, 'Нет такого абонента'))

    

Задание 7

Напишите программу, которая:

  • получает на вход две строки;
  • формирует словарь, в котором ключи взяты из первой строки, а значения (целые числа) – из второй;
  • выводит Есть, есть ли в словаре значения, равные 5, и Нет в противном случае.

Пример ввода:

        яблоки груши апельсины лимоны киви
2 7 9 5 1

    

Вывод:

        Есть
    

Решение:

        sp1 = input().split()
sp2 = map(int, input().split())
my_dict = dict(zip(sp1, sp2))
print('Есть' if 5 in my_dict.values() else 'Нет')

    

Задание 8

Напишите программу, которая получает на вход целое число от 1 до 12, и выводит название месяца, порядковому номеру которого соответствует введенное число. Если пользователь ввел число, которое меньше или больше допустимого – вывести подсказку Введите число от 1 до 12.

Пример ввода:

        10
    

Вывод:

        Октябрь
    

Решение:

        months = {1: 'Январь', 2: 'Февраль', 3: 'Март', 4: 'Апрель',
       	5: 'Май', 6: 'Июнь', 7: 'Июль', 8: 'Август',
      	9: 'Сентябрь', 10: 'Октябрь', 11: 'Ноябрь', 12: 'Декабрь'}
num = int(input())
print(months.get(num, 'Введите число от 1 до 12'))

    

Задание 9

Напишите программу, которая:

  • Принимает на вход 3 строки с названиями стран и расположенными в них городами.
  • Получает от пользователя название города и выводит страну, в которой он находится.

Пример ввода:

        Австрия Вена Инсбрук Линц Грац
Испания Барселона Мадрид Малага Севилья
Франция Париж Марсель Лион Ницца
Грац

    

Вывод:

        Австрия
    

Решение:

        my_dict = {k:v for _ in range(3) for k, *v in  [input().split()]}
city = input()
[print(k) for k, v in my_dict.items() if city in v]

    

Задание 10

Имеется следующий словарь:

        numbers = {'dict1': [11, 20, 30, 17, 6, 24, 90, 15, 17],
          	'dict2': [21, 33, 40, 10, 29, 31, 90, 12],
          	'dict3': [52, 34, 20, 21, 44, 22, 10, 87],
          	'dict4': [22, 54, 29, 21, 70, 88, 99, 34],
          	'dict5': [21, 40, 29, 21, 19, 32, 68, 77],
          	'dict6': [14, 60, 70, 10, 55, 61, 84, 99],
          	'dict7': [45, 80, 12, 23, 42, 22, 37, 90],
          	'dict8': [13, 14, 15, 26, 48, 92, 36, 11],
          	'dict9': [12, 70, 18, 28, 18, 28, 53, 91],
          	'dict10': [29, 79, 18, 28, 18, 28, 32, 55]}
    

Напишите программу, которая удалит из значений словаря все четные числа.

Решение:

        numbers = {key: [i for i in value if i % 2 != 0] for key, value in numbers.items()}
print(numbers)

    

Подведем итоги

Словари и генераторы словарей помогают в решении задач, связанных с подсчетом, множественным выбором, хранением и обработкой значений, описывающих свойства объектов. Во многих случаях словари позволяют избежать использования многоуровневых условий if… elif… else. В следующей статье будем изучать методы кортежей.

***

Содержание самоучителя

  1. Особенности, сферы применения, установка, онлайн IDE
  2. Все, что нужно для изучения Python с нуля – книги, сайты, каналы и курсы
  3. Типы данных: преобразование и базовые операции
  4. Методы работы со строками
  5. Методы работы со списками и списковыми включениями
  6. Методы работы со словарями и генераторами словарей
  7. Методы работы с кортежами
  8. Методы работы со множествами
  9. Особенности цикла for
  10. Условный цикл while
  11. Функции с позиционными и именованными аргументами
  12. Анонимные функции
  13. Рекурсивные функции
  14. Функции высшего порядка, замыкания и декораторы
  15. Методы работы с файлами и файловой системой
  16. Регулярные выражения
  17. Основы скрапинга и парсинга
  18. Основы ООП: инкапсуляция и наследование
  19. Основы ООП – абстракция и полиморфизм
  20. Графический интерфейс на Tkinter
  21. Основы разработки игр на Pygame
  22. Основы работы с SQLite
  23. Основы веб-разработки на Flask
  24. Основы работы с NumPy
  25. Основы анализа данных с Pandas
***

Материалы по теме

МЕРОПРИЯТИЯ

Комментарии

ВАКАНСИИ

Добавить вакансию
C# Developer
Москва, по итогам собеседования
AppSec Business Partner
по итогам собеседования

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ