Python 2.7执行b.append(int(j))时触发Memory Error的问题咨询
首先,咱们得先理清楚为什么2.8MB的文件会让28GB内存的机器爆内存——这看起来很反直觉,但问题大概率出在你处理数据的方式,而不是文件本身的大小。
可能的原因分析
单个超大整数的转换开销
如果你的0.txt里是一整行数百万位的纯数字字符串(比如一个2.8MB长的数字),那把它转换成Python的int时,因为Python的整数是任意精度的,内部会用数组来存储二进制形式的数字,再加上Python对象的额外开销(引用计数、类型信息等),这个转换过程可能会瞬间占用远超文本大小的内存——虽然28GB看起来很大,但极端情况下(比如数字长度达到数千万位),还是可能触发内存错误。逐个字符转int并存储到列表
如果你的代码是遍历每行的每个字符,把每个字符转成int后添加到列表里(比如for j in line: b.append(int(j))),那2.8MB的文本大概有290万个字符。在64位Python2.7中,每个int对象大约要占28字节,290万*28字节≈81MB——理论上这远小于你的内存,但如果你的代码同时还有其他内存占用,或者存在内存碎片问题,也可能触发错误。分割成大量小整数的内存累积
如果文本是用分隔符(比如逗号、空格)分割的大量数字,每个数字转成int后都存在列表里,虽然单个int不大,但架不住数量多——不过几百万个int也才几百MB,还是不至于让28GB内存爆掉,除非你还有其他内存密集型操作。
解决方案
根据不同的场景,你可以试试下面的方法:
避免不必要的大整数转换
如果你的业务不需要把那个超长数字转成int(比如只是需要校验、截取部分数字),直接操作字符串就行,完全不用转换,这样内存占用就是文件本身的大小。用生成器分批处理,不要全存到列表
如果需要处理分割后的多个数字,别一次性把所有数字都存入列表,而是用生成器按需生成,处理完一个就释放一个:def get_numbers(file_path): with open(file_path, 'r') as f: line = f.read().strip() # 这里假设用逗号分隔,根据你的实际分隔符修改 for num_str in line.split(','): yield int(num_str) # 逐个处理数字,不用一次性存到列表 for num in get_numbers('0.txt'): # 这里写你的处理逻辑 print(num)使用更高效的数据结构
如果必须存储大量整数,用Python的array模块代替普通列表——它存储的是原始二进制数据,内存占用比普通列表小得多:import array # 用'l'表示长整型,根据你的数字大小选合适的类型(比如'i'是普通int) num_array = array.array('l') with open('0.txt', 'r') as f: line = f.read().strip() for num_str in line.split(','): num_array.append(int(num_str))这种方式每个整数只占用4或8字节,比普通列表的28字节节省了70%以上的内存。
考虑升级到Python3
Python2.7已经停止维护多年,Python3在内存管理、大整数处理上都有不少优化,很多Python2的内存问题在Python3里都能自动解决。
内容的提问来源于stack exchange,提问作者papabiceps




