Так у вас есть два списка: список слов, которые вы хотите проверить, и, возможно, удалить, и список правильных слов. Если вам нравится, вы можете использовать тот же список для обеих целей, но я предполагаю, что у вас есть два списка.
Для скорости вы должны превратить список допустимых слов в набор. Затем вы можете очень быстро проверить, не найдено ли какое-либо конкретное слово в этом наборе. Затем возьмите каждое слово и проверьте, существуют ли все его префиксы в списке действительных слов или нет. Поскольку слова «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)
Если вы являетесь поклонником остротами, вы могли бы сделать прочь с для списка и использовать список понимание:
newlst = [word for word in lst if not any(w in valid for w in subwords(word))]
Я думаю, что это более красноречиво, чем должно быть, и мне нравится, когда можно отлаживать заявления печати.
Хмм, если подумать об этом, это не слишком лаконичным, если вы просто добавить еще одну функцию:
def keep(word):
return not any(w in valid for w in subwords(word))
newlst = [word for word in lst if keep(word)]
Python может быть легко читать и понимать, если вы делаете такие функции, как это, и дать им хорошие имена ,
Есть ли два списка? Один из словаря и один, содержащий ваши «корневые» слова? – aqua
Вы предлагаете двунаправленную пару циклов, одну для каждого целевого слова, а другую для вызова метода '.startswith()' для каждого целевого слова для каждого слова в допустимом списке. Это было бы довольно медленно. Python для циклов не самый быстрый, и в любом случае Python предоставляет некоторые полезные структуры данных с быстрым поиском. В таких проблемах вы должны подумать: «Какие структуры данных в Python помогут здесь?» Словарь возможен, но набор идеален здесь. Это будет проще и быстрее, просто попробуйте различные подстроки целевого слова в быстром наборе поиска, как я и предложил. – steveha