""" Урок 36. Словари. Продолжение — весь код примеров одним файлом. Источник: subjects/python-fundamentals/course/lessons/36-dictionaries-continued/examples.html Файл собран автоматически (tools/build_lesson_examples.py): правьте страницу урока. Запуск: python lesson-36.py """ # ==================================================================== # Пример 1. Четыре способа создать словарь - один результат # ==================================================================== d_literal = {"a": 1, "b": 2, "c": 3} d_call = dict(a=1, b=2, c=3) d_pairs = dict([("a", 1), ("b", 2), ("c", 3)]) keys = ["a", "b", "c"] values = [1, 2, 3] d_zip = dict(zip(keys, values)) d_comp = {x: x ** 2 for x in range(6) if x % 2 == 0} print(d_literal) # {'a': 1, 'b': 2, 'c': 3} print(d_call) # {'a': 1, 'b': 2, 'c': 3} print(d_pairs) # {'a': 1, 'b': 2, 'c': 3} print(d_zip) # {'a': 1, 'b': 2, 'c': 3} print(d_comp) # {0: 0, 2: 4, 4: 16} print(d_literal == d_call == d_pairs) # True - все три способа дали одинаковый словарь # ==================================================================== # Пример 2. get(): безопасное чтение без KeyError # ==================================================================== user = {"name": "Alice", "age": 30} print(user.get("age")) # 30 print(user.get("city")) # None - ключа нет, но ошибки нет print(user.get("city", "Unknown")) # Unknown - свой default вместо None print(user) # {'name': 'Alice', 'age': 30} - словарь не изменился # ==================================================================== # Пример 3. setdefault(): тот же вопрос, но словарь меняется # ==================================================================== d = {"a": 1, "b": 2} print(d.setdefault("a")) # 1 - ключ уже был, вернул его значение print(d.setdefault("c")) # None - ключа не было, создал c=None print(d.setdefault("d", 0)) # 0 - ключа не было, создал d=0 print(d) # {'a': 1, 'b': 2, 'c': None, 'd': 0} - словарь ИЗМЕНИЛСЯ # ==================================================================== # Пример 4. get() и setdefault() дают одинаковый счётчик # ==================================================================== text = "Что говорить, когда нечего говорить?".lower() counter_get = {} for char in text: counter_get[char] = counter_get.get(char, 0) + 1 counter_set = {} for char in text: counter_set[char] = counter_set.setdefault(char, 0) + 1 print(counter_get) # {'ч': 2, 'т': 3, 'о': 7, ' ': 4, 'г': 4, 'в': 2, 'р': 2, 'и': 2, # 'ь': 2, ',': 1, 'к': 1, 'д': 1, 'а': 1, 'н': 1, 'е': 2, '?': 1} print(counter_get == counter_set) # True - оба варианта совпали # ==================================================================== # Пример 5. Группировка списком: здесь setdefault() выигрывает # ==================================================================== words = ["кот", "корова", "собака", "слон", "кошка", "сорока"] grouped_setdefault = {} for word in words: grouped_setdefault.setdefault(word[0], []).append(word) grouped_get = {} for word in words: key = word[0] grouped_get[key] = grouped_get.get(key, []) # grouped_get.get(key, []).append(word) не сработает - # append() возвращает None, а не список grouped_get[key].append(word) print(grouped_setdefault) # {'к': ['кот', 'корова', 'кошка'], 'с': ['собака', 'слон', 'сорока']} print(grouped_get == grouped_setdefault) # True - результат один и тот же # ==================================================================== # Пример 6. dict.fromkeys(): словарь с одинаковым значением # ==================================================================== letters = ["x", "y", "z"] print(dict.fromkeys(letters)) # {'x': None, 'y': None, 'z': None} print(dict.fromkeys(letters, 0)) # {'x': 0, 'y': 0, 'z': 0} # ==================================================================== # Пример 7. Ловушка fromkeys(): один список на всех # ==================================================================== keys = ["a", "b", "c"] bad = dict.fromkeys(keys, []) bad["a"].append(1) print(bad) # {'a': [1], 'b': [1], 'c': [1]} - "потянулись" все три! print(bad["a"] is bad["b"]) # True - это буквально один и тот же список good = {key: [] for key in keys} good["a"].append(1) print(good) # {'a': [1], 'b': [], 'c': []} - списки независимые # ==================================================================== # Пример 8. Сравнение словарей: содержимое, а не порядок # ==================================================================== d1 = {"a": 1, "b": 2} d2 = {"b": 2, "a": 1} d3 = {"b": 2, "a": "1"} print(d1 == d2) # True - содержимое одинаковое, порядок ключей другой print(d1 == d3) # False - значение 1 (int) != '1' (str) print(d1 != d3) # True e1 = {"a": 1, "b": 2, "c": 3} e2 = {"b": 20, "c": 3, "d": 4} print(sorted(e1.keys() & e2.keys())) # ['b', 'c'] - общие ключи print(sorted(e1.keys() - e2.keys())) # ['a'] - есть только в e1 print(sorted(e1.keys() ^ e2.keys())) # ['a', 'd'] - есть только в одном из двух print(sorted(e1.keys() | e2.keys())) # ['a', 'b', 'c', 'd'] - объединение ключей # ==================================================================== # Пример 9. Объединение словарей: | и update() # ==================================================================== a = {"x": 1, "y": 2} b = {"y": 20, "z": 3} merged = a | b print(merged) # {'x': 1, 'y': 20, 'z': 3} - справа побеждает при конфликте print(a) # {'x': 1, 'y': 2} - a не изменился, | создаёт НОВЫЙ словарь c = {"x": 1, "y": 2} c.update(b) print(c) # {'x': 1, 'y': 20, 'z': 3} - update() меняет c НА МЕСТЕ # ==================================================================== # Пример 10. keys(), values(), items() - живые view objects # ==================================================================== profile = {"name": "Alice", "age": 30} keys_view = profile.keys() print(keys_view) # dict_keys(['name', 'age']) profile["city"] = "New York" print(keys_view) # dict_keys(['name', 'age', 'city']) - view "увидел" новый ключ for key, value in profile.items(): print(key, "->", value) # name -> Alice # age -> 30 # city -> New York snapshot = list(profile.keys()) profile["country"] = "USA" print(snapshot) # ['name', 'age', 'city'] - список - это снимок, а не view # ==================================================================== # Пример 11. defaultdict как альтернатива setdefault() # ==================================================================== from collections import defaultdict groups = defaultdict(list) for word in words: groups[word[0]].append(word) print(groups) # defaultdict(, {'к': ['кот', 'корова', 'кошка'], 'с': ['собака', 'слон', 'сорока']}) print(dict(groups)) # {'к': ['кот', 'корова', 'кошка'], 'с': ['собака', 'слон', 'сорока']}