如何提高Python中该随机文本生成器的效率?
我正在做一个随机文本生成器——不使用马尔可夫链——目前运行得还不错。首先,这是我的代码流程:
输入一个句子作为起始句子——这个叫做触发字符串,赋值给一个变量。
找出触发字符串中最长的单词。
在古腾堡项目的数据库中搜索包含这个单词的句子——不管是大写还是小写。
返回包含我在第三步提到的单词的最长句子。
把第一步和第四步得到的句子拼在一起。
把第四步的句子作为新的“触发”句子,然后重复这个过程。注意,我需要在第二个句子中找出最长的单词,然后继续这样做,依此类推。
这是我的代码:
import nltk
from nltk.corpus import gutenberg
from random import choice
triggerSentence = raw_input("Please enter the trigger sentence: ")#get input str
longestLength = 0
longestString = ""
listOfSents = gutenberg.sents() #all sentences of gutenberg are assigned -list of list format-
listOfWords = gutenberg.words()# all words in gutenberg books -list format-
while triggerSentence:
#so this is run every time through the loop
split_str = triggerSentence.split()#split the sentence into words
#code to find the longest word in the trigger sentence input
for piece in split_str:
if len(piece) > longestLength:
longestString = piece
longestLength = len(piece)
#code to get the sentences containing the longest word, then selecting
#random one of these sentences that are longer than 40 characters
sets = []
for sentence in listOfSents:
if sentence.count(longestString):
sents= " ".join(sentence)
if len(sents) > 40:
sets.append(" ".join(sentence))
triggerSentence = choice(sets)
print triggerSentence
我担心的是,这个循环大多数时候会重复打印同一句话。因为它是包含最长单词的最长句子。为了避免重复得到同一句话,我想到了以下方法:
*如果当前句子中的最长单词和上一句中的最长单词相同,就直接把这个最长单词从当前句子中删除,然后找下一个最长的单词。
我尝试了一些实现方法,但由于涉及到列表和列表的列表——因为古腾堡模块中的单词和句子——我没能成功应用上述解决方案。有没有什么建议可以帮助我找到第二个最长的单词?我似乎无法通过解析简单的字符串输入来做到这一点,因为NLTK的古腾堡模块的.sents()和.words()函数分别返回列表的列表和列表。谢谢大家的帮助。
2 个回答
如果你只是想生成随机的文本(我猜是希望这些文本能包含有意义的句子),其实可以更简单:只需要生成一些随机数字,然后用这些数字去你的文本数据库中查找句子(比如说Project Gutenberg或者其他地方的文本)。
这里有一些建议可以改进你的代码:
你现在的
while
循环会一直运行下去,建议把它去掉。可以使用
max
和生成器表达式来找出最长的单词,这样会更节省内存。你应该用列表推导式生成一个包含长度超过40个字符的句子列表,并且这些句子里要有
longestWord
。这个操作也应该从while
循环中移除,因为它只需要执行一次。代码示例:
sents = [" ".join(sent) for sent in listOfSents if longestWord in sent and len(sent) > 40]
如果你想随机顺序打印出找到的每个句子,可以尝试打乱你刚创建的列表:
for sent in random.shuffle(sents): print sent
根据这些建议,代码可能会变成这样:
import nltk
from nltk.corpus import gutenberg
from random import shuffle
listOfSents = gutenberg.sents()
triggerSentence = raw_input("Please enter the trigger sentence: ")
longestWord = max(triggerSentence.split(), key=len)
longSents = [" ".join(sent) for sent in listOfSents
if longestWord in sent
and len(sent) > 40]
for sent in shuffle(longSents):
print sent