下面是一个不那么令人印象深刻但更具解释性的解决方案:
让我们从定义问题中的示例词典和句子开始:
sentence = 'I am done; Look at that, cat!'
dictionary = {
'!': 'sentinel',
',': 'sentinel',
',': 'sentinel',
'I': 'pronoun',
'that': 'pronoun',
'cat': 'noun',
'am': 'verb',
'Look': 'verb',
'done': 'verb',
'at': 'preposition',
';': 'preposition',
}
对于我的解决方案,我定义了一个递归解析函数,恰当地命名为
parse
.
解析
首先将一个句子按空格分隔成单词,然后尝试通过在提供的词典中查找每个单词来对其进行分类。
如果在字典里找不到这个词(因为它附有标点符号等),
解析
然后将该单词拆分为其组件标记,并从中递归地解析它。
def parse(sentence, dictionary):
# split the words apart by whitespace
# some tokens may still be stuck together. (i.e. "that,")
words = sentence.split()
# this is a list of strings containing the 'category' of each word
output = []
for word in words:
if word in dictionary:
# base case, the word is in the dictionary
output.append(dictionary[word])
else:
# recursive case, the word still has tokens attached
# get all the tokens in the word
tokens = [key for key in dictionary.keys() if key in word]
# sort all the tokens by length - this makes sure big words are more likely to be preserved. (scat -> s, cat or sc, at) check
tokens.sort(key=len)
# this is where we'll store the output
sub_output = None
# iterate through the tokens to find if there's a valid way to split the word
for token in tokens:
try:
# pad the tokens inside each word
sub_output = parse(
word.replace(token, f" {token} "),
dictionary
)
# if the word is parsable, no need to try other combinations
break
except:
pass # the word couldn't be split
# make sure that the word was split - if it wasn't it's not a valid word and the sentence can't be parsed
assert sub_output is not None
output.append(sub_output)
# put it all together into a neat little string
return ' '.join(output)
下面是您使用它的方法:
# usage of parse
output = parse(sentence, dictionary)
# display the example output
print(output)
我希望我的回答能让你对解决这个问题的另一种方法有更多的了解。
塔达!