在python内存错误

问题描述 投票:31回答:5
Traceback (most recent call last):
File "/run-1341144766-1067082874/solution.py", line 27, in 
main()
File "/run-1341144766-1067082874/solution.py", line 11, in main
if len(s[i:j+1]) > 0:
MemoryError
Error in sys.excepthook:
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/apport_python_hook.py", line 64, in apport_excepthook
from apport.fileutils import likely_packaged, get_recent_crashes
File "/usr/lib/python2.7/dist-packages/apport/__init__.py", line 1, in 
from apport.report import Report
MemoryError

Original exception was:
Traceback (most recent call last):
File "/run-1341144766-1067082874/solution.py", line 27, in 
main()
File "/run-1341144766-1067082874/solution.py", line 11, in main
if len(s[i:j+1]) > 0:
MemoryError

当我试图运行下面的程序上面的错误出现。有人能解释一下什么是内存错误,以及如何解决这个问题? 。该方案需要字符串作为输入,并发现所有可能的子串和创建一组(在词典编纂顺序)在它外面并应用户要求的各索引处打印该值,否则应该打印“无效”

def main():
    no_str = int(raw_input())
    sub_strings= []
    for k in xrange(0,no_str):
        s = raw_input()
        a=len(s)
        for i in xrange(0, a):
            for j in xrange(0, a):
                if j >= i:
                    if len(s[i:j+1]) > 0:
                        sub_strings.append(s[i:j+1])
    sub_strings = list(set(sub_strings))
    sub_strings.sort()
    queries= int(raw_input())
    resul = []
    for i in xrange(0,queries):
        resul.append(int(raw_input()))
    for p in resul:
        try:
            print sub_strings[p-1]
        except IndexError:
            print 'INVALID'


if __name__ == "__main__":
   main()
python memory
5个回答
20
投票

这一次在这里:

s = raw_input()
a=len(s)
for i in xrange(0, a):
    for j in xrange(0, a):
        if j >= i:
            if len(s[i:j+1]) > 0:
                sub_strings.append(s[i:j+1])

似乎是非常低效和昂贵的大型字符串。

做的更好

for i in xrange(0, a):
    for j in xrange(i, a): # ensures that j >= i, no test required
        part = buffer(s, i, j+1-i) # don't duplicate data
        if len(part) > 0:
            sub_Strings.append(part)

缓冲对象保持到原来的字符串的引用,并开始和长度属性。这样一来,会出现数据没有不必要的重复。

长度l的串具有平均长度l*l/2l/2子字符串,所以存储器消耗将大致是l*l*l/4。有了缓冲,它要小得多。

需要注意的是buffer()只有在2.x的存在3.X具有memoryview(),其中使用稍有不同。

更妙的是计算指标和切出的子需求。


27
投票

如果你得到意想不到的MemoryError,你认为你应该有足够的可用RAM,这可能是因为你使用的是32位的Python安装。

最简单的办法,如果你有一个64位的操作系统,是切换到64位安装蟒。

问题是,32位的蟒蛇只能访问的RAM〜4GB。这可如果你的操作系统是因为操作系统开销的32位,甚至进一步萎缩。

您可以详细了解为什么32位操作系统被限制到这里RAM〜4GB:https://superuser.com/questions/372881/is-there-a-technical-reason-why-32-bit-windows-is-limited-to-4gb-of-ram


8
投票

一个memory error意味着你的程序运行内存不足。这意味着你的程序以某种方式创建太多的对象。

在你的榜样,你要寻找那些能消耗大量内存的算法的部分。我怀疑你的程序给予很长的字符串作为输入。因此,s[i:j+1]可能是罪魁祸首,因为它会创建一个新的列表。你使用它虽然是第一次,因为你不使用创建的列表是没有必要的。您可以尝试查看是否存在以下帮助:

if  j + 1 < a:
    sub_strings.append(s[i:j+1])

要更换第二列表的创建,你一定要使用buffer对象,通过glglgl的建议。

还要注意,由于您使用if j >= i:,你不需要为0,开始您的xrange您可以:

for i in xrange(0, a):
    for j in xrange(i, a):
        # No need for if j >= i

一个更激进的替代办法是设法返工你的算法,这样你就不会预先计算所有可能的子字符串。相反,你可以简单地计算所要求的子字符串。


1
投票

你可以尝试创建一个弹出式菜单的错误,从外部脚本导入将剧本分成几个脚本相同的脚本。例如,hello.py期待一个错误内存错误,所以我把hello.py到几个脚本h.py e.py ll.py o.py个个都进入一个文件夹“hellohello”到该文件夹​​中创建初始化。 PY到初始化写进口H,E,LL,邻然后在IDE你写进口hellohello


-1
投票

使用Python的64位解决了很多问题。

© www.soinside.com 2019 - 2024. All rights reserved.