Введение

В Python словарь — это упорядоченная (начиная с Python 3.7) коллекция пар ключ: значение. Словари используются для хранения значений данных таким образом, что они являются изменяемыми (mutable), индексируемыми и не допускают дублирования ключей. Основные операции со словарем — это сохранение значения по ключу и извлечение значения по заданному ключу.

Например, вы можете создать словарь для хранения информации о коте:

## Словарь: коллекция пар ключ-значение
my_cat = {
    'size': 'fat',          ## ключ: 'size', значение: 'fat'
    'color': 'gray',        ## ключ: 'color', значение: 'gray'
    'disposition': 'loud'   ## ключ: 'disposition', значение: 'loud'
}

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

Доступ к данным словаря и их изменение

На этом шаге вы узнаете, как создавать словарь, добавлять новые пары ключ-значение, обновлять существующие и извлекать значения с помощью оператора подстроки (субскрипта) [].

Вы можете добавить или обновить запись в словаре, присвоив значение ключу с помощью оператора []. Если ключ уже существует, его значение обновляется. Если ключ не существует, добавляется новая пара ключ-значение.

Примечание: Если вы не знакомы с использованием WebIDE (похожего на VS Code), пожалуйста, изучите его сначала в этой лаборатории.

Давайте начнем с создания файла для написания нашего кода.

Сначала откройте файл main.py, расположенный в каталоге ~/project в проводнике файлов слева.

Теперь добавьте следующий код в main.py. Этот код определяет словарь, а затем добавляет в него новую пару ключ-значение.

## Add or update dictionary entry using subscript operator
my_cat = {
 'size': 'fat',
 'color': 'gray',
 'disposition': 'loud',
}
my_cat['age_years'] = 2  ## Add new key-value pair
print(my_cat)

Чтобы запустить скрипт, откройте терминал и выполните следующую команду:

python3 main.py

Вы должны увидеть обновленный словарь, напечатанный в консоли:

{'size': 'fat', 'color': 'gray', 'disposition': 'loud', 'age_years': 2}

Вы также можете извлечь значение, используя ключ внутри оператора подстроки []. Давайте изменим файл main.py, чтобы получить доступ и вывести значение, связанное с ключом 'size'.

Замените содержимое main.py следующим кодом:

my_cat = {
 'size': 'fat',
 'color': 'gray',
 'disposition': 'loud',
}
print(my_cat['size'])

Снова запустите скрипт:

python3 main.py

Вывод будет значением ключа 'size':

fat

Имейте в виду, что если вы попытаетесь получить доступ к ключу, которого нет в словаре, Python вызовет исключение KeyError. Давайте посмотрим на это в действии. Замените код в main.py на этот:

my_cat = {
 'size': 'fat',
 'color': 'gray',
 'disposition': 'loud',
}
print(my_cat['eye_color'])

Запустите скрипт:

python3 main.py

Это приведет к возникновению KeyError, поскольку ключ 'eye_color' не существует в словаре my_cat.

Traceback (most recent call last):
  File "/home/labex/project/main.py", line 5, in <module>
    print(my_cat['eye_color'])
KeyError: 'eye_color'

Для проверки, пожалуйста, верните main.py к первому примеру, который добавляет новый ключ и выводит весь словарь.

## Add or update dictionary entry using subscript operator
my_cat = {
 'size': 'fat',
 'color': 'gray',
 'disposition': 'loud',
}
my_cat['age_years'] = 2  ## Add new key-value pair
print(my_cat)

Итерация по словарям

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

Итерация по значениям с помощью values()

Метод values() возвращает объект представления (view object), который отображает список всех значений в словаре. Вы можете перебрать этот объект для доступа к каждому значению.

Очистите файл main.py и добавьте следующий код:

## Итерация по значениям словаря с использованием метода .values()
pet = {'color': 'red', 'age': 42}
for value in pet.values():  ## Цикл по всем значениям
    print(value)

Запустите скрипт:

python3 main.py

В выводе каждое значение будет показано на новой строке:

red
42

Итерация по ключам с помощью keys()

Аналогично, метод keys() возвращает объект представления, содержащий ключи словаря. Хотя вы можете использовать pet.keys(), прямая итерация по самому словарю является более распространенным и "питоническим" (Pythonic) способом перебора его ключей.

Обновите main.py следующим кодом:

## Итерация по словарю напрямую перебирает ключи (поведение по умолчанию)
pet = {'color': 'red', 'age': 42}
for key in pet:  ## Эквивалентно for key in pet.keys()
    print(key)

Запустите скрипт:

python3 main.py

Вы увидите напечатанные ключи:

color
age

Итерация по парам ключ-значение с помощью items()

Метод items() очень полезен, когда вам нужны и ключ, и значение во время итерации. Он возвращает объект представления, где каждый элемент представляет собой кортеж (ключ, значение).

Обновите main.py для использования items():

## Итерация по парам ключ-значение с использованием метода .items()
pet = {'color': 'red', 'age': 42}
for key, value in pet.items():  ## Распаковка кортежа в key и value
    print(f'Key: {key} Value: {value}')

Здесь мы используем распаковку кортежа (for key, value in ...), чтобы присвоить первый элемент кортежа переменной key, а второй — переменной value при каждой итерации.

Запустите скрипт:

python3 main.py

Вывод будет в виде отформатированных строк, показывающих каждую пару ключ-значение:

Key: color Value: red
Key: age Value: 42

Безопасный доступ и добавление элементов

На этом шаге вы узнаете, как безопасно извлекать значения, не вызывая ошибку KeyError, и как условно добавлять элементы.

Безопасное извлечение с помощью get()

Как вы видели на Шаге 1, попытка получить доступ к несуществующему ключу с помощью [] вызывает KeyError. Метод get() предоставляет более безопасный способ доступа к ключам. Он возвращает значение для ключа, если он существует, но если его нет, он возвращает None вместо вызова ошибки.

Очистите main.py и добавьте следующий код:

## Метод .get(): безопасное извлечение значения, возвращает None, если ключ не существует
wife = {'name': 'Rose', 'age': 33}

print(f'My wife name is {wife.get("name")}')
print(f'She is deeply in love with {wife.get("husband")}')

Запустите скрипт:

python3 main.py

Вывод показывает, что get() вернул значение для 'name' и None для отсутствующего ключа 'husband':

My wife name is Rose
She is deeply in love with None

Вы также можете передать значение по умолчанию в get() в качестве второго аргумента. Это значение будет возвращено, если ключ не найден.

Измените main.py, чтобы указать значение по умолчанию:

wife = {'name': 'Rose', 'age': 33}

print(f'She is deeply in love with {wife.get("husband", "lover")}')

Запустите его снова:

python3 main.py

Теперь в выводе используется ваше пользовательское значение по умолчанию:

She is deeply in love with lover

Условное добавление с помощью setdefault()

Метод setdefault() предлагает краткий способ добавить пару ключ-значение только в том случае, если ключ еще не существует. Он проверяет наличие ключа; если он присутствует, он возвращает значение этого ключа. Если его нет, он вставляет ключ с указанным значением и возвращает это значение.

Обновите main.py для использования setdefault():

wife = {'name': 'Rose', 'age': 33}
wife.setdefault('has_hair', True) ## 'has_hair' не существует, поэтому он добавляется.
wife.setdefault('name', 'Lily') ## 'name' существует, поэтому словарь не изменяется.
print(wife)

Запустите скрипт:

python3 main.py

Вывод показывает, что 'has_hair' был добавлен, но значение для 'name' не было обновлено:

{'name': 'Rose', 'age': 33, 'has_hair': True}

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

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

Удаление с помощью pop()

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

Очистите main.py и добавьте следующий код, чтобы увидеть pop() в действии:

wife = {'name': 'Rose', 'age': 33, 'hair': 'brown'}
removed_value = wife.pop('age')
print(f"Removed value: {removed_value}")
print(wife)

Запустите скрипт:

python3 main.py

В выводе показано удаленное значение и словарь после удаления:

Removed value: 33
{'name': 'Rose', 'hair': 'brown'}

Удаление с помощью popitem()

Метод popitem() удаляет последний вставленный элемент в словаре (в Python 3.7+). Он возвращает удаленный элемент в виде кортежа (ключ, значение).

Измените main.py для использования popitem():

wife = {'name': 'Rose', 'age': 33, 'hair': 'brown'}
removed_item = wife.popitem()
print(f"Removed item: {removed_item}")
print(wife)

Запустите скрипт:

python3 main.py

Последний элемент, ('hair', 'brown'), удаляется и выводится:

Removed item: ('hair', 'brown')
{'name': 'Rose', 'age': 33}

Удаление с помощью ключевого слова del

Ключевое слово del можно использовать для удаления элемента по его ключу. Оно не возвращает значение удаленного элемента.

Измените main.py для использования del:

wife = {'name': 'Rose', 'age': 33, 'hair': 'brown'}
del wife['age']
print(wife)

Запустите скрипт:

python3 main.py

Словарь выводится без ключа 'age':

{'name': 'Rose', 'hair': 'brown'}

Удаление всех элементов с помощью clear()

Метод clear() удаляет все элементы из словаря, оставляя его пустым.

Измените main.py для использования clear():

wife = {'name': 'Rose', 'age': 33, 'hair': 'brown'}
wife.clear()
print(wife)

Запустите скрипт:

python3 main.py

Вывод — пустой словарь:

{}

Для проверки убедитесь, что ваш main.py использует pop() для удаления ключа 'age' и выводит итоговый словарь.

wife = {'name': 'Rose', 'age': 33, 'hair': 'brown'}
wife.pop('age')
print(wife)

Операции утилит словарей

На этом шаге вы познакомитесь с некоторыми полезными утилитами для работы со словарями, включая проверку наличия ключей и значений, "красивую" печать (pretty-printing) и слияние словарей.

Проверка наличия ключей и значений с помощью in

Вы можете использовать оператор in для проверки существования ключа в словаре.

Очистите main.py и добавьте этот код:

person = {'name': 'Rose', 'age': 33}

print(f"'name' in person: {'name' in person}")
print(f"'height' in person: {'height' in person}")

Запустите скрипт:

python3 main.py

Вывод показывает True для существующего ключа и False для несуществующего:

'name' in person: True
'height' in person: False

Вы также можете использовать in с методом values(), чтобы проверить, существует ли значение в словаре.

Измените main.py:

person = {'name': 'Rose', 'age': 33}

print(f"'Rose' in person.values(): {'Rose' in person.values()}")
print(f"33 in person.values(): {33 in person.values()}")
print(f"'John' in person.values(): {'John' in person.values()}")

Запустите его:

python3 main.py

Вывод:

'Rose' in person.values(): True
33 in person.values(): True
'John' in person.values(): False

"Красивая" печать с помощью pprint

Когда словари большие, их прямая печать может привести к длинной и трудночитаемой строке. Модуль pprint предоставляет возможность "красивой печати" (pretty-print) для форматирования словарей в более читаемом виде.

Обновите main.py:

import pprint

wife = {'name': 'Rose', 'age': 33, 'has_hair': True, 'hair_color': 'brown', 'height': 1.6, 'eye_color': 'brown'}
pprint.pprint(wife)

Запустите скрипт:

python3 main.py

Вывод аккуратно отформатирован, ключи отсортированы в алфавитном порядке:

{'age': 33,
 'eye_color': 'brown',
 'hair_color': 'brown',
 'has_hair': True,
 'height': 1.6,
 'name': 'Rose'}

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

Вы можете объединить два словаря, используя оператор распаковки словаря ** (доступен в Python 3.5+). Если есть совпадающие ключи, будет использовано значение из второго словаря.

Обновите main.py следующим кодом:

dict_a = {'a': 1, 'b': 2}
dict_b = {'b': 3, 'c': 4}
dict_c = {**dict_a, **dict_b}
print(dict_c)

Запустите скрипт:

python3 main.py

Вывод — новый словарь, содержащий все элементы из обоих. Обратите внимание, что значение для ключа 'b' равно 3, которое берется из dict_b.

{'a': 1, 'b': 3, 'c': 4}

Резюме

Поздравляем с завершением этой лабораторной работы по словарям Python!

В этой лабораторной работе вы изучили основные операции для работы с одной из самых мощных структур данных Python. Вы рассмотрели:

  • Создание, доступ и изменение: Использование {} для создания словарей и оператора подстроки (subscript operator) [] для добавления, обновления и извлечения данных.
  • Итерация: Перебор ключей, значений и пар ключ-значение с использованием методов keys(), values() и items().
  • Безопасные операции: Использование get() для избежания KeyError и setdefault() для условного добавления элементов.
  • Удаление элементов: Использование pop(), popitem(), ключевого слова del и clear() для удаления элементов.
  • Вспомогательные операции: Проверка принадлежности с помощью оператора in, форматирование вывода с помощью pprint и слияние словарей с помощью оператора распаковки **.

Освоение словарей — это важнейший шаг на пути к тому, чтобы стать опытным программистом на Python. Продолжайте практиковать эти концепции для создания более сложных и эффективных приложений.