我正在尝试制作Markov文本生成器,但我一直得到我不理解的KeyError
。
在此功能中,我在行Keyerror
中始终得到一个w1, w2 = w2, random.choice(self.wordlog[w1])
。self.gensize
是我要生成的单词数,self.size
是我文字中的单词总数,self.wordlog
是字典-即{'secondly': ['because', 'because'], 'pardon': ['cried', 'cried', 'said', 'said', 'your', 'she'], 'limited': ['to', 'warranty', 'right', 'right', 'to'], etc...}
def generate(self):
startseed = random.randint(0, self.size - 1)
w1, w2 = self.words[startseed], self.words[startseed+1]
#at this point, w1 and w2 are a random word and a following word-i.e. alice ran
wordlist = []
for i in range(self.gensize):
wordlist.append(w1)
w1, w2 = w2, random.choice(self.wordlog[w1])
#i.e. self.wordlog[alice] should return a list of all the values the word alice precedes
wordlist.append(w2)
print wordlist
当我运行函数(
print markov("alice.txt", 5).generate()
)时,我每次都会得到一个KeyError
-一个不同的词(这是可以预料的,因为起始种子和random.choice都会导致这种情况)。有人看到这有什么问题以及如何解决吗?
编辑:
这是其余的代码,因此您可以查看
self.words
的来源以及其他所有内容:class markov(object):
def __init__(self, filename, gensize):
self.wordlog = {}
self.filename = filename
self.words = self.file_to_words()
self.size = len(self.words)
self.gensize = gensize
def file_to_words(self):
with open(self.filename, "r") as file_opened:
text = file_opened.read().translate(None, string.punctuation)
mixedcasewords = text.split()
words = [x.lower() for x in mixedcasewords]
return words
def doubles(self):
for i in range((self.size)-1):
yield (self.words[i], self.words[i+1])
def catalog(self):
for w1, w2 in self.doubles():
self.wordlog.setdefault(w1, []).append(w2)
print self.wordlog
最佳答案
我认为这是因为您将random.choice
与dict
而不是list
/ set
/ tuple
很难说,但也许您应该检查self.wordlog
以确保。
for k,v in self.wordlog.items():
if type(v) != list: print("This shouldn't happen! Check: '"+k+"'")
[编辑]
也许只是在尝试满足给定的gensize达到不存在的键的时候。
print markov("alice.txt", 5).generate()
用五个迭代开始一个
for
循环。对于每次迭代,您都应确保随机选择的键w1
实际上是wordlog
的键。为确保这不是问题,您可以做两件事:
方法1
检查
w1 in wordlog
或else: break
。这种方法可能会提供比所需大小小的解决方案。
方法2
确保它适用于任何给定的大小。
您可以轻松地在循环中链接wordlog键和值,
就像在
{'a':['b','a'],'b':['b','a']}
中