【问题标题】:Memory Error with function calling large parameters函数调用大参数时出现内存错误
【发布时间】:2015-03-19 06:27:19
【问题描述】:

节目:

这是一个程序,它试图在给出一个句子的起始词列表 (seedBank) 和一个词对字典 (pairs) 后创建一个乱码语句,该字典包含来自文本文件的信息,即哪些词跟在哪个词后面.

包含“这是一只猫”的 text.txt 文件示例。他是一条狗。这意味着我们将输入以下内容:

seedBank = ['This', 'He']

pairs = { 'This':['is'],'is':['a','a'],'a':['cat','dog'],'He':['is'] } 

因此,该函数使用这些输入来创建一个随机生成的句子,该句子具有模糊的意义,因为它遵循半语法正确的格式。

def gibberish_sentence(seedBank, pairs):
    gibSentence = []
    gibSentence.append(random.choice(seedBank)) #random seed
    x = gibSentence[0]
    while(pairs.get(x)is not None): #Loop while value x is a key in the dictionairy
        y = random.choice(pairs.get(x)) #random value of key x
        gibSentence.append(y) #random value is added to main string
        x = y #key x is reset to y
    return ' '.join(gibSentence) #String

问题:

这个程序可以很好地传递像上面这样带有一组定义的 random.seed(value) 的小句子,但是当给定一组非常大的输入(seedBank 和对)时,它会失败并返回内存错误。因此,我的问题是这个程序的哪些问题可能会导致它在处理更大的参数时出现问题?

请注意,这些参数实际上并不大,我没有文本文档,但它不会太大,例如没有足够的 RAM。

错误代码:

非常感谢。

已解决:谢谢!问题已解决,实际上是导致问题的 while 条件,这是它循环遍历整个文本,而不是仅在到达带有句号或问号等的单词时结束。本质上,这导致它过载记忆,但感谢大家的帮助!

【问题讨论】:

  • 文本文件有多大?在 KB 的顺序上?兆?国标?另外,我认为我们需要查看调用代码——我敢打赌,你不小心复制了占用大量内存的东西。
  • 不幸的是,这是一个自动化测试系统,但我已通过电子邮件向提供测试的人发送电子邮件,以便我可以手动检查它,我认为问题可能与下面提到的无限循环有关,但我会考虑到这一点。文本文件只有 9.5KB,所以出了点问题!
  • 谢谢!问题已解决,实际上是导致问题的 while 条件,这是它循环遍历整个文本,而不是仅在到达带有句号或问号等的单词时结束。本质上,这导致它过载记忆,但感谢大家的帮助!

标签: python memory


【解决方案1】:

如果没有您的实际pairs,这很难说,但如果所有单词在某个时间点相互引用,则可能会出现无限循环:

pairs = { 'someone':['thinks'],'thinks':['that','how'],'that':['someone','anyone'],'how':['someone'], 'anyone': ['thinks'] } 

永远不会结束。

【讨论】:

  • 这是一个我没有想到的有效点,因为该函数只想生成一个句子,它应该在单词有 .或者 ?或者 !因为它是最后一个字符,因此我可能需要为此添加一个测试用例。不幸的是,这是一个自动化测试系统的输出,我自己没有 word_pairs_bank :/ 谢谢你的回复!
【解决方案2】:

正如 Tim Pietzcker 所提到的,如果 pairs 中有一个循环,您的代码可以永远循环。这是最基本的例子:

>>> seedBank = ['and']
>>> pairs = {'and': ['on'], 'on': ['and']}
>>> gibberish_sentence(seedBank, pairs)  # just keeps going

您可以通过修改 pairs 字典来确保生成的句子(最终)结束,以便当单词作为句子中的最后一个单词出现时,它包含一个标记值。例如,对于像“你、我和狗”这样的源文本。

seedBank = ['You']

pairs = {
    'You': ['and'],
    'and': ['me', 'the'],
    'me': ['and'],
    'the': ['dog'],
    'dog': ['.'],
}

...并为gibberish_sentence() 中的哨兵添加检查:

def gibberish_sentence(seedBank, pairs):
    gibSentence = []
    gibSentence.append(random.choice(seedBank)) #random seed
    x = gibSentence[0]
    while(pairs.get(x)is not None): #Loop while value x is a key in the dictionairy
        y = random.choice(pairs.get(x)) #random value of key x
        if y == '.':
            break
        gibSentence.append(y) #random value is added to main string
        x = y #key x is reset to y
    return ' '.join(gibSentence) #String

...这让句子有机会终止:

>>> gibberish_sentence(seedBank, pairs)
'You and the dog'
>>> gibberish_sentence(seedBank, pairs)
'You and me and me and me and me and me and the dog'
>>> gibberish_sentence(seedBank, pairs)
'You and me and the dog'

【讨论】:

    【解决方案3】:

    加入字符串列表并不是最差的,但在空间效率方面也不是最好的。

    考虑使用 StringIO 之类的东西(当然未经测试):

    from cStringIO import StringIO
    import random
    
    def gibberish_sentence(seedBank, pairs):
        seed = random.choice(seedBank)
        gibSentence = StringIO()
        gibSentence.write(seed)             #random seed
        gibSentence.write(' ')
        x = seed
        while(pairs.get(x) is not None):    #Loop while value x is a key in the dictionairy
            y = random.choice(pairs.get(x)) #random value of key x
            gibSentence.write(y)            #random value is added to main string
            gibSentence.write(' ')
            x = y                           #key x is reset to y
        return gibSentence.getvalue() #String
    

    Here's a comparison 的不同字符串连接方法,在每秒操作数和内存消耗方面。

    【讨论】:

    • 您好,感谢您的回复!是的,对不起,我对 Python 语法很陌生,所以我真的只是在学习绳索,我不认为这个特殊问题是由串联引起的,但感谢您的效率提示!
    【解决方案4】:

    可以通过使用非常节省内存的生成器来避免构建列表。

    def gibberish_sentence(seedBank, pairs):
        x = random.choice(seedBank)) #random seed
        yield x
        while(pairs.get(x)is not None): #Loop while value x is a key in the dictionairy
            y = random.choice(pairs.get(x)) #random value of key x
            yield y
            x = y #key x is reset to y
    
    print ' '.join(gibberish_sentence(seedBank, pairs)) #String
    

    或者字符串必须在函数内构建,可以这样做,

    def gibberish_sentence(seedBank, pairs):
        def words():
            x = random.choice(seedBank)) #random seed
            yield x
            while(pairs.get(x)is not None): #Loop while value x is a key in the dictionairy
            y = random.choice(pairs.get(x)) #random value of key x
            yield y
            x = y #key x is reset to y
        return ' '.join(words()) #String
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多