Поздравляем, это последняя задача в подборке!
Завершим её на высокой ноте — теперь вы объедините всё, что узнали о множествах, списочных выражениях и фильтрации данных.
В этом задании вы проанализируете текст и определите пары слов, которые имеют не менее трёх общих букв.
Важно: порядок слов в паре не имеет значения, а повторяющиеся буквы не считаются несколько раз.
Вашему решению будет предоставлена переменная text
.
Напишите выражение для генерации множества, содержащего все кортежи пар слов, имеющих более двух общих букв без учёта повторений.
Пары с разным порядком слов следует считать одной и той же и включать в результат только в одном (лексикографически упорядоченном) виде.
Примечание
В решении не должно быть ничего, кроме списочного выражения.
Подсказка:
Используйте вложенные в списочное выражение циклы для перебора всех пар.
Для фильтрации преобразуйте слова в множества и найдите их пересечение.
Сортируйте слова в кортежах для избежания повторов.
Пример
Ввод
text = 'ехали медведи на велосипеде'
Вывод
{('велосипеде', 'медведи'), ('велосипеде', 'ехали')}
Ввод
text = 'а за ними кот задом наперед'
Вывод
set()
Решение
Это задание надо делать по частям.
Для начала нам надо разбить строку на слова с помощью split(). Затем перебрать все возможные пары слов, как мы это делали в L. Максимальное произведение. После чего исключить повторящиеся слова и организовать уникальность пар. Проще всего это сделать с помощью проверки w1 < w2. Она исключит совпадения слов и ситуацию, когда значения w1 и w2 поменяются местами. Так же нам потребуется извлечь из слов все уникальные буквы, что мы легко умеем делать, например, с помощью set(w1). остается найти пересечение этих множеств и если они больше или равны трем (или больше двух), создать кортеж, предварительно отсортировав слова.
words = text.split()
result = set()
for i in range(len(words)):
for j in range(i + 1, len(words)):
word1 = words[i]
word2 = words[j]
common_letters = set(word1) & set(word2)
if len(common_letters) >= 3:
pair = tuple(sorted([word1, word2]))
result.add(pair)
Остается завернуть эту логику в одну строку. К сожалению мы не сможем использовать нормальные имена переменных, в силу ограничения на длину строки в хендбуке, а переносить строки я не люблю. Поэтому в решении будут однобуквенные переменные.
Если честно, я бы в рабочем коде предпочел развернутый вариант, тем более, что его можно и нужно оптимизировать:
words = text.split()
letter_sets = {word: set(word) for word in words}
result = set()
for i in range(len(words)):
for j in range(i + 1, len(words)):
word1 = words[i]
word2 = words[j]
common_letters = letter_sets[word1] & letter_sets[word2]
if len(common_letters) >= 3:
pair = tuple(sorted([word1, word2]))
result.add(pair)
В таком виде на длинных словах можно получить ощутимый прирост производительности.
Посмотреть код
Решение
{tuple(sorted([w1, w2])) for w1 in text.split() for w2 in text.split() if w1 < w2 and len(set(w1) & set(w2)) >= 3}