Перейти к содержимому
Теория · Словари и множества · урок 1 из 11

Словари

Чему вы научитесь

Чему вы научитесь:

  • читать, добавлять и менять пары словаря по ключу;
  • читать отсутствующий ключ без ошибки с помощью get;
  • считать, сколько раз встречается каждое слово;
  • убирать повторы и сравнивать наборы с помощью множеств.
Табличка фруктового прилавка: в строке pear рядом с названием стоит цена 70

Представьте фруктовый прилавок, над которым висит табличка с ценами. В каждой строке слева название фрукта, справа цена: в строке pear стоит 70.

Чтобы узнать цену груши, продавец не пересчитывает строки. Он находит строку по названию и читает цену рядом с ним.

Теперь попробуйте хранить те же цены в двух списках: в одном названия, в другом цены. Чтобы узнать цену груши, придётся найти номер "pear" в первом списке и взять элемент с тем же номером из второго. К тому же списки расходятся: название из одного удалили, а цену из другого забыли.

Словарь хранит пары, как строки таблички: по ключу сразу находится значение. Ключ — это название в строке, значение — цена рядом с ним:

Python
prices = {"pear": 70, "plum": 40}
print(prices["pear"])  # 70
prices["kiwi"] = 90
prices["plum"] = 45
print(prices)  # {'pear': 70, 'plum': 45, 'kiwi': 90}
print(len(prices))  # 3

Давайте разберём пример по строкам:

  1. prices = {"pear": 70, "plum": 40} создаёт словарь из двух пар.
  2. prices["pear"] находит пару с ключом "pear" и даёт 70.
  3. prices["kiwi"] = 90 добавляет на табличку новую строку: ключа "kiwi" ещё не было.
  4. prices["plum"] = 45 не добавляет строку, а меняет цену сливы.
  5. print(prices) показывает все три пары, а len(prices) возвращает их число — 3.

Чтение и запись

Словарь в коде записывают в фигурных скобках: пары «ключ: значение» через запятую. Значение читают по ключу в квадратных скобках, как элемент списка по индексу. Запись по ключу работает в двух вариантах:

  • запись по новому ключу добавляет пару;
  • запись по существующему ключу заменяет её значение.

Поэтому каждый ключ встречается в словаре один раз, а len возвращает число пар. Здесь аналогия с табличкой перестаёт работать. На настоящей табличке можно дважды написать pear с разными ценами, а в словаре вторая запись заменит первую.

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

Что ещё нужно знать о словаре:

  • значением может быть что угодно: число, строка, список;
  • пустой словарь записывают как {};
  • инструкция del prices["kiwi"] удаляет пару вместе с ключом;
  • оператор in проверяет ключи, а не значения: "pear" in prices даёт True, а 70 in prices — False.

Два имени, один словарь

Как и список, словарь при b = a не копируется: оба имени ведут к одной и той же табличке. Запись через b видна и через a.

Отдельную копию с теми же парами дают два способа:

  • dict(prices) строит новый словарь из пар старого;
  • prices.copy() делает то же самое методом словаря.

Метод get

Чтение отсутствующего ключа в квадратных скобках останавливает программу ошибкой. Это как спросить у продавца цену киви, которого на табличке нет. Метод get читает без ошибки: для отсутствующего ключа он возвращает None или второй аргумент, если тот передан.

Python
stock = {"apple": 3, "pear": 0}
print(stock.get("plum"))  # None
print(stock.get("plum", 10))  # 10
print(stock.get("pear", 10))  # 0
print("plum" in stock)  # False

Разберём по строкам:

  1. stock.get("plum") даёт None: ключа "plum" нет, а второго аргумента не передали.
  2. stock.get("plum", 10) даёт 10: ключа по-прежнему нет, и get возвращает второй аргумент.
  3. stock.get("pear", 10) даёт 0: ключ "pear" есть, и get возвращает его значение, хотя оно и ложное.
  4. "plum" in stock даёт False: сам словарь get не меняет, и ключ "plum" в нём не появился.

Второй аргумент используется, только когда ключа нет. Передавайте в нём то, что означает отсутствие: 0 для остатка на складе или пустую строку для имени.

Этот вопрос часто задают на собеседовании: «Чем d[k] отличается от d.get(k)?» Ответ:

  • d[k] для отсутствующего ключа вызывает ошибку KeyError;
  • d.get(k) возвращает None, а d.get(k, x) — x;
  • ни один из них не добавляет ключ в словарь.

Частая ошибка

Ключ читают в квадратных скобках, не проверив, что он есть:

Python
stock = {"apple": 3, "pear": 0}
print(stock["plum"])  # ✗
TEXT
KeyError: 'plum'

Ошибка KeyError называет ключ, которого нет в словаре. Если отсутствующий ключ — обычный случай, читайте значение через get или сначала проверьте "plum" in stock в if. Например, stock.get("plum", 0) даёт 0, и программа продолжает работу.

Главное

  • Словарь хранит пары «ключ — значение»: d[k] читает значение, а d[k] = v добавляет пару или заменяет значение.
  • Каждый ключ встречается в словаре один раз, а in проверяет ключи.
  • b = a даёт второе имя тому же словарю, а копию дают dict(a) и a.copy().
  • d.get(k, x) возвращает x вместо ошибки KeyError, если ключа нет.

Подпишись, чтобы пройти курс

Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.

Войти другим способом