Простая учебная задача проверки орфографии на Python

В прошлом году согласился стать модератором на популярном курсе по программированию на Python (рекомендую, замечательный бесплатный курс). Мне это нужно в первую очередь для того, чтобы самому Python не забывать. Потому что без практики кодинг довольно быстро приходит в увядание и от элегантного pythonic way вскоре остаются одни паскалевские операторы 🙂

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

Итак, задача звучит так:

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

Напишем подобную систему.

Через стандартный ввод подаётся следующая структура: первой строкой — количество d записей в списке известных слов, после передаётся d строк с одним словарным словом на строку, затем — количество l строк текста, после чего — l строк текста.

Напишите программу, которая выводит слова из текста, которые не встречаются в словаре. Регистр слов не учитывается. Порядок вывода слов произвольный. Слова, не встречающиеся в словаре, не должны повторяться в выводе программы.

Sample Input:

3
a
bb
cCc
2
a bb aab aba ccc
c bb aaa

Sample Output:

aab
aba
c
aaa

_

Решение:

dic = {input().lower() for _ in range(int(input()))}

wrd = set()
for _ in range(int(input())):
    wrd |= {i.lower() for i in input().split()}

print(*(wrd-dic), sep="\n")

_
Пояснения:

# формируем множество известных слов на основании построчного ввода
dic = {input().lower() for _ in range(int(input()))}

# заводим пустое множество для приема текста

wrd = set()

# т.к. текст построчно подается, а также в каждой строке несколько слов,
# то каждую строку превращаем во множество и добавляем в единое множество wrd

for _ in range(int(input())):
    wrd |= {i.lower() for i in input().split()}

# на вывод отправляем результат вычитания словарного множества dic
# из текстового множества wrd; впереди ставим *, чтобы раскрыть поэлементно

print(*(wrd-dic), sep="\n")

_
Замечания:

  1. Основа работы кода — свойство множеств хранить только уникальные значения
  2. wrd |= {…} отвечает за добавление множества {…} в единое wrd (аналог метода update)
  3. обращаем внимание на звездочку *, которая вытаскивает элементы на вывод, вместо того, чтобы печатать в виде множества
  4. используется символ «_» для обозначения индексных переменных
  5. в случаях, когда можно использовать несколько подходов, добиваемся единообразия: например, wrd.difference(dic) даст тот же эффект, что (wrd-dic), но если выше мы использовали оператор wrd |= вместо метода update, то и вместо difference используем оператор