如何提高Python中该随机文本生成器的效率?

4 投票
2 回答
2180 浏览
提问于 2025-04-16 03:27

我正在做一个随机文本生成器——不使用马尔可夫链——目前运行得还不错。首先,这是我的代码流程:

  1. 输入一个句子作为起始句子——这个叫做触发字符串,赋值给一个变量。

  2. 找出触发字符串中最长的单词。

  3. 在古腾堡项目的数据库中搜索包含这个单词的句子——不管是大写还是小写。

  4. 返回包含我在第三步提到的单词的最长句子。

  5. 把第一步和第四步得到的句子拼在一起。

  6. 把第四步的句子作为新的“触发”句子,然后重复这个过程。注意,我需要在第二个句子中找出最长的单词,然后继续这样做,依此类推。

这是我的代码:

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 个回答

1

如果你只是想生成随机的文本(我猜是希望这些文本能包含有意义的句子),其实可以更简单:只需要生成一些随机数字,然后用这些数字去你的文本数据库中查找句子(比如说Project Gutenberg或者其他地方的文本)。

1

这里有一些建议可以改进你的代码:

  1. 你现在的 while 循环会一直运行下去,建议把它去掉。

  2. 可以使用 max 和生成器表达式来找出最长的单词,这样会更节省内存。

  3. 你应该用列表推导式生成一个包含长度超过40个字符的句子列表,并且这些句子里要有 longestWord。这个操作也应该从 while 循环中移除,因为它只需要执行一次。

    代码示例:sents = [" ".join(sent) for sent in listOfSents if longestWord in sent and len(sent) > 40]

  4. 如果你想随机顺序打印出找到的每个句子,可以尝试打乱你刚创建的列表:

    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

撰写回答