Итак, у вас есть два списка: список слов, которые вы хотите проверить и, возможно, удалить, и список допустимых слов. Если хотите, вы можете использовать один и тот же список для обеих целей, но я предполагаю, что у вас есть два списка.
Для скорости вы должны превратить ваш список допустимых слов в набор. Затем вы можете очень быстро проверить, есть ли какое-то конкретное слово в этом наборе. Затем возьмите каждое слово и проверьте, существуют ли все его префиксы в списке допустимых слов или нет. Поскольку «a» и «I» являются допустимыми словами на английском языке, вы удалите все допустимые слова, начинающиеся с «a», или у вас будет правило, устанавливающее минимальную длину префикса?
Я использую файл / usr / share / dict / words из моей установки Ubuntu. В этом файле много разных странных вещей; например, он, кажется, содержит каждую букву как слово. Таким образом, "k" там, "q", "z" и т. Д. Насколько мне известно, ни одно из этих слов не является словом, но они, вероятно, присутствуют там по какой-то технической причине. Во всяком случае, я решил просто исключить что-нибудь короче, чем три буквы из моего списка допустимых слов.
Вот что я придумал:
# build valid list from /usr/dict/share/words
wfile = "/usr/dict/share/words"
valid = set(line.strip() for line in open(wfile) if len(line) >= 3)
lst = ["ark", "booze", "kite", "live", "rodeo"]
def subwords(word):
for i in range(len(word) - 1, 0, -1):
w = word[:i]
yield w
newlst = []
for word in lst:
# uncomment these for debugging to make sure it works
# print "subwords", [w for w in subwords(word)]
# print "valid subwords", [w for w in subwords(word) if w in valid]
if not any(w in valid for w in subwords(word)):
newlst.append(word)
print(newlst)
Если вы фанат однострочников, вы можете покончить с списком «for» и использовать понимание списка:
newlst = [word for word in lst if not any(w in valid for w in subwords(word))]
Я думаю, что это более кратко, чем должно быть, и мне нравится возможность вставлять операторы print для отладки.
Хм, если подумать, это не слишком кратко, если вы просто добавите еще одну функцию:
def keep(word):
return not any(w in valid for w in subwords(word))
newlst = [word for word in lst if keep(word)]
Python может быть легко читаемым и понятным, если вы создадите такие функции и дадите им хорошие имена.