Урок 9. Словари и множества
Список хранит значения по номерам. Но часто удобнее искать значение не по номеру, а по названию: столицу — по стране, цену — по товару, телефон — по имени. Для этого есть словарь. А когда важно только, есть значение или нет, и повторы не нужны, — множество.
Словарь
Словарь (dict) хранит пары ключ: значение в фигурных скобках. По ключу значение находится сразу, без перебора:
capitals = {"Беларусь": "Минск", "Польша": "Варшава", "Литва": "Вильнюс"}
print(capitals["Беларусь"])
capitals["Латвия"] = "Рига"
print(len(capitals))
print("Литва" in capitals)
print(capitals.get("Франция", "неизвестно"))Минск
4
True
неизвестноd[ключ]— значение по ключу;d[ключ] = значение— добавить пару или заменить значение, если ключ уже есть;ключ in d— есть ли такой ключ;d.get(ключ, запасное)— значение или запасное, если ключа нет.
Если взять через квадратные скобки ключ, которого нет, программа остановится с ошибкой KeyError: 'Франция'. get такой ошибки не даёт: без второго аргумента он возвращает None.
Ключи в словаре не повторяются. Ключом может быть строка, число или кортеж, но не список: изменяемое значение ключом быть не может.
Перебор словаря
for по словарю перебирает ключи. Пары целиком даёт метод items(), только значения — values(), только ключи — keys():
fruits = {"яблоки": 5, "груши": 3, "сливы": 12}
for name, count in fruits.items():
print(name, "—", count)
print(sum(fruits.values()))
print(list(fruits.keys()))яблоки — 5
груши — 3
сливы — 12
20
['яблоки', 'груши', 'сливы']Пары перебираются в том порядке, в котором добавлялись.
Изменение и удаление
stock = {"хлеб": 10, "молоко": 4}
stock["хлеб"] -= 3
stock["сыр"] = 2
del stock["молоко"]
print(stock)
removed = stock.pop("сыр")
print(removed, stock){'хлеб': 7, 'сыр': 2}
2 {'хлеб': 7}del d[ключ] удаляет пару, d.pop(ключ) удаляет и возвращает значение.
Частый приём: подсчёт
Сколько раз встречается каждое слово? Ключ — слово, значение — счётчик. get(word, 0) даёт 0 для слова, которое встретилось впервые:
text = "мама мыла раму мама"
counts = {}
for word in text.split():
counts[word] = counts.get(word, 0) + 1
print(counts)
for word in sorted(counts):
print(word, counts[word]){'мама': 2, 'мыла': 1, 'раму': 1}
мама 2
мыла 1
раму 1sorted(counts) даёт ключи словаря по алфавиту. Для подсчёта есть и готовое средство — Counter из модуля collections, но устроен он так же.
Множество
Множество (set) хранит значения без повторов и без порядка. Из списка с повторами оно оставляет каждое значение по одному разу:
nums = [3, 1, 3, 2, 1, 3]
unique = set(nums)
print(len(unique))
print(sorted(unique))
print(2 in unique)3
[1, 2, 3]
Trueset(список)— множество из списка,{1, 2, 3}— множество сразу;- пустое множество — только
set(): запись{}создаёт пустой словарь; s.add(x)добавляет значение,s.discard(x)убирает его (ошибки не будет, еслиxнет);x in sпроверяется очень быстро, даже если в множестве миллион значений.
Порядок элементов в множестве не гарантирован. Если результат нужно вывести по порядку, его сортируют: sorted(s).
Операции с множествами
| Запись | Результат |
|---|---|
a | b | объединение: всё, что есть хотя бы в одном |
a & b | пересечение: то, что есть в обоих |
a - b | разность: то, что есть в a, но нет в b |
a ^ b | то, что есть ровно в одном из двух |
a = {1, 2, 3, 4}
b = {3, 4, 5}
print(sorted(a | b))
print(sorted(a & b))
print(sorted(a - b))
print(sorted(a ^ b))[1, 2, 3, 4, 5]
[3, 4]
[1, 2]
[1, 2, 5]Пример — сколько разных слов во фразе без учёта регистра:
text = input()
words = set(text.lower().split())
print(len(words))Кот и пёс и кот3Кортеж
Ещё один набор значений — кортеж (tuple): как список, только в круглых скобках и неизменяемый. (3, 4) — кортеж из двух чисел. Кортеж возвращает функция с return a, b, кортежем может быть ключ словаря: например, координаты клетки (строка, столбец).
Что выбрать
| Задача | Что взять |
|---|---|
| значения по порядку, с повторами, доступ по номеру | список [] |
| значение по названию: страна → столица | словарь {ключ: значение} |
только уникальные значения, быстрая проверка in | множество set() |
| неизменяемый набор, ключ словаря | кортеж () |
Коротко
- Словарь —
{ключ: значение};d[k]— значение,d[k] = v— добавить или заменить. - Нет ключа —
KeyError; безопасно —d.get(k, запасное); проверка —k in d. - Перебор пар —
for k, v in d.items(); значения —d.values(). - Множество — значения без повторов:
set(список); пустое —set(), не{}. |— объединение,&— пересечение,-— разность; для вывода по порядку —sorted.