Сокращение словаря списков в Python


Я работаю со словарем для программы anagram на Python. Ключи-это кортежи отсортированных букв, а значения-массивы возможных слов с этими буквами:

wordlist = {
   ('d', 'g', 'o'): ['dog', 'god'],
   ('a', 'c', 't'): ['act', 'cat'],
   ('a', 's', 't'): ['sat', 'tas'],
}

Я использую регулярное выражение для фильтрации списка вниз. Таким образом, учитывая r't$' в качестве фильтра, конечный результат должен быть:

filtered_list = {
   ('a', 'c', 't'): ['act', 'cat'],
   ('a', 's', 't'): ['sat'],
}

Пока что я свел его к двум ступеням. Во-первых, сохраните все слова, соответствующие выражению:

tmp = {k: [w for w in v if re.search(r't$', w)] for k, v in wordlist.items()}

Это оставляет меня с пустыми списками:

{
   ('d', 'g', 'o'): [],
   ('a', 'c', 't'): ['act', 'cat'],
   ('a', 's', 't'): ['sat'],
}

Тогда мне нужен второй проход, чтобы избавиться от пустых списков:

filtered_list = {k: v for k, v in tmp.items() if v}
Я уверен, что есть способ сделать это за один шаг, но я еще не понял этого. Есть ли способ объединить их? Или лучший способ сделать это вообще?
2 7

2 ответа:

Выполнение этого в два этапа прекрасно и, вероятно, хорошо для удобства чтения.

Но чтобы ответить на ваш вопрос, вот одна строчка (разбитая на несколько строк для удобства чтения). Он использует выражение генератора для генерации пар с первого шага.
{
  k:v for k, v in
  (
    (kk, [w for w in vv if re.search(r't$', w)])
    for kk, vv in wordlist.items()
  )
  if v
}
=> {('a', 'c', 't'): ['act', 'cat'], ('a', 's', 't'): ['sat']}

Для одного лайнера, что-то вроде этого?

A = {k:[w for w in v if re.search(r't$', w)] for k,v in wordlist.items() if any(re.search(r't$', w) for w in v)}