Множества и словари

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

Коротко про функцию хеширования:

Множества и hash()

Хеш объекта в python используется в первую очередь для предварительного сравнения

⇒ Специальная функция hash() — числовой хеш от константного объекта

Почему id() — плохая хеш-функция?

Множества

Множества в Python реализованы как хеш-таблицы:

LecturesCMC/PythonIntro2025/06_SetsDicts/set.svg

Элементы множества не упорядочены (можно заметить следы упорядочивания по хешам, с учётом перехеширования и масштабирования):

   1 >>> s = {str(i) for i in range(10,30)}
   2 >>> s
   3 {'18', '19', '25', '29', '23', '27', '16', '11', '17', '20', '15', '28', '14', '24', '26', '13', '22', '10', '12', '21'}
   4 >>> [hash(c)%128 for c in s]
   5 [8, 10, 11, 10, 25, 32, 39, 40, 39, 64, 72, 76, 95, 100, 106, 110, 115, 122, 125, 127]
   6 

Множества — модифицируемые объекты, но есть и константные: frozenset

Дополнительное свойство: хеш составного объекта разный для разных запусков интерпретатора (туда однократно подмешивается случайное значение). Иначе можно было бы подобрать такое множество, на котором операции бы имели линейную сложность.

Словари

Задача: хранить произвольные объекты, каждый из которых однозначно соответствует хорошо хешируемой константе.

{i} Использование

Python 3.15+ — frozendict

Словари внутри Python

Передача пространства имён как параметра

Именные параметры функции

Позиционные параметры — кортеж, именные — словарь.

Модуль collections

Д/З

  1. Прочитать и прощёлкать
  2. EJudge: PopularWord 'Самое популярное слово'

    Ввести построчно текст, состоящий из пробелов, переводов строки и латинских букв, и заканчивающийся пустой строкой. Вывести слово, которое чаще других встречается в тексте, если оно такое одно, и ---, если таких слов несколько.

    Input:

    Sed tempus ipsum quis eros tempus lacinia Cras finibus lorem ut lacinia egestas nunc nibh iaculis est convallis tincidunt
    mi mi sed nisl Sed porttitor aliquam elit ullamcorper tincidunt arcu euismod quis Mauris congue elit suscipit leo varius
    facilisis Cras et arcu sodales laoreet est vitae pharetra orci Integer eget nulla dictum aliquet justo semper molestie neque
    Maecenas bibendum lacus tincidunt auctor varius purus felis ullamcorper dui et laoreet ligula ex et risus Donec eget
    fringilla nibh Cras congue tincidunt accumsan Maecenas euismod eleifend elit ut rhoncus tortor sodales a Cras egestas
    finibus lorem non tempor tincidunt aera
    Output:

    tincidunt
  3. EJudge: MumboJumbo 'Мумбо-Юмбо'

    Ввод представляет собой строки из букв латинского алфавита (последняя строка — пустая). Это письмена на языках двух племён: Mumbo и Jumbo. Слова из двух языков идут попеременно: на строках с чётным номером — из одного языка, на строках с нечётным — из другого (какого — неизвестно). Языки Mumbo и Jumbo имеют одинаковые гласные и разные согласные, причём согласных в языке Mumbo больше, чем в Jumbo. Все слова начинаются на гласную. Определить и вывести, какому языку — Mumbo или Jumbo — принадлежит первое слово, если известно, что в данном корпусе текстов:

    1. Использованы все начальные гласные (буква, на которую не начинается ни одно слово — согласная)
    2. Использованы все согласные
    Input:

    obmdobo
    oututo
    odbann
    ufututu
    omdan
    uputupf
    adabo
    utupopot
    obomna
    utpouo
    amdm
    Output:

    Mumbo
  4. EJudge: PublicFriend 'Знаком со всеми'

    Вводятся в столбик пары неотрицательных целых чисел через запятую. Каждая пара M, N обозначает взаимное знакомство людей под номерами M и N. Ввод заканчивается парой 0, 0 (не учитывается, и вообще человек N считается незнакомым с человеком N ;) ). Вывести через пробел в порядке возрастания номера тех, кто знаком со всеми остальными, или пустую строку, если таких нет.

    Input:

    7, 9
    1, 7
    9, 2
    9, 2
    9, 7
    2, 9
    9, 2
    2, 9
    7, 1
    9, 2
    9, 2
    2, 1
    7, 2
    7, 9
    7, 1
    7, 1
    0, 0
    Output:

    2 7
  5. EJudge: ThreeSquares 'Три квадрата'

    Ввести произвольную последовательность (не обязательно кортеж) натуральных чисел, не превышающих 200000. Вывести, сколько среди них различных чисел, являющихся суммой трёх квадратов натуральных чисел.

    • Пояснение. Входная последовательность должна обрабатываться так: seq = set(eval(input()))

    Input:

    3, 4, 2, 9, 1, 5, 6, 7, 8, 3, 6
    Output:

    3

LecturesCMC/PythonIntro2026/06_SetsDicts (последним исправлял пользователь FrBrGeorge 2026-10-19 15:04:09)