Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 列表太大的Memoryerror_Python - Fatal编程技术网

Python 列表太大的Memoryerror

Python 列表太大的Memoryerror,python,Python,我正在用python编写脚本,现在我必须创建一个包含248956422个整数的非常大的列表。重点是,这个表中的一些“0”将被更改为1、2或3,因为我有8个列表,4个是基因的起始位置,4个是基因的结束位置。 关键是我必须多次迭代“anno”,因为替换0的数字可能会随着其他迭代而改变。 “Anno”必须写入文件才能创建注释文件。 这里是我的问题,我如何划分,或在运行中进行划分,以不获取memoryerror,包括替换“0”表示其他人,替换1,2,3表示其他人。 Mabye在重写文件吗?我在等待你的建

我正在用python编写脚本,现在我必须创建一个包含248956422个整数的非常大的列表。重点是,这个表中的一些“0”将被更改为1、2或3,因为我有8个列表,4个是基因的起始位置,4个是基因的结束位置。 关键是我必须多次迭代“anno”,因为替换0的数字可能会随着其他迭代而改变。 “Anno”必须写入文件才能创建注释文件。 这里是我的问题,我如何划分,或在运行中进行划分,以不获取memoryerror,包括替换“0”表示其他人,替换1,2,3表示其他人。 Mabye在重写文件吗?我在等待你的建议,请问我是否不太清楚我写了什么:P

whole_st_gen = [] #to make these lists more clear for example
whole_end_gen = [] # whole_st_gen has element "177" 
whole_st_ex = [] # and whole_end_gen has "200" so from position 177to200
whole_end_ex = [] # i need to put "1"
whole_st_mr = [] # of course these list can have even 1kk+ elements
whole_end_mr = [] # note that every st/end of same kind have equal length
whole_st_nc = [] 
whole_end_nc = [] #these lists are including some values of course
length = 248956422 
anno = ['0' for i in range(0,length)] # here i get the memoryerror
#then i wanted to do something like..
for j in range(0, len(whole_st_gen)):
    for y in range(whole_st_gen[j],whole_end_gen[j]):
        anno[y]='1'

与使用列表理解创建列表不同,我建议使用一个迭代器创建一个迭代器,该迭代器根据需要生成数字,而不是将所有数字保存在内存中。此外,您不需要在循环中使用
I
,因为它只是一个一次性变量,您不需要使用它

anno = ('0' for _ in range(0,length)) # In python 2.X use xrange() instead of range() 
但请注意,and迭代器是一次性的iterable,您不能在对其进行一次迭代后使用它。如果您想多次使用它,您可以使用它创建独立的迭代器

还请注意,如果要根据条件更改某些元素,则不能就地更改它。您可以通过迭代迭代器并使用生成器表达式应用条件来创建新的迭代器

例如:

new_anno =("""do something with i""" for i in anno if #some condition)

您可以使用
bytearray
对象来获得比整数列表更紧凑的内存表示:

anno = bytearray(b'\0' * 248956422)
print(anno[0])  # → 0
anno[0] = 2
print(anno[0])  # → 2
print(anno.__sizeof__())  # → 248956447 (on my computer)

通过动态确定
anno
中每个元素的值,您可能会更好:

def anno():
    for idx in xrange(248956422):
        elm = "0"

        for j in range(0, len(whole_st_gen)):
            if whole_st_gen[j] <= idx < whole_end_gen[j]:
                elm = "1"                    

        for j in range(0, len(whole_st_ex)):
            if whole_st_ex[j] <= idx < whole_end_ex[j]:
                elm = "2"                    

        for j in range(0, len(whole_st_mr)):
            if whole_st_mr[j] <= idx < whole_end_mr[j]:
                elm = "3"                    

        for j in range(0, len(whole_st_nc)):
            if whole_st_nc[j] <= idx < whole_end_nc[j]:
                elm = "4"                    

        yield elm
这当然是可行的,但它只会导致应用的
整个*.\u ex
的更改,并且在写入文件时需要将它们组合起来,这可能有点尴尬:

for a, b, c, d in zip(anno_st(), anno_ex(), anno_mr(), anno_nc()):
    if d != "0":
        write_to_file(d)
    elif c != "0":
        write_to_file(c)
    elif b != "0":
        write_to_file(b)
    else:
        write_to_file(a)
但是,如果您只想应用某些更改集,则可以编写一个将其作为参数的函数:

def anno(*args):
    for idx in xrange(248956422):
        elm = "0"

        for st, end, tag in args:
             for j in range(0, len(st)):
                 if st <= idx < end[j]:
                      elm = tag

        yield tag

你的python版本是什么?你到底需要什么?例如,
anno
是否包含与
“0”
不同的248956422元素?如何修改anno等?我的python版本是2.7.1@Kasramvd@skyking,我的意思是迭代一次,将“1”从“整”st/end/\u gen”改为“1”,然后我需要再次迭代,将“1”中的一部分从“整”st/end\ex改为“2”,对于_mr和_nc也是如此。然后anno list将被写入文件。如果数据是迭代器,您也不能修改数据(如问题所示)。@skyking确实如此,但可以通过在当前迭代器上迭代并创建一个新的迭代器来完成!是的,但那可能效率很低。@skyking为什么是高效的???使用列表理解,您需要在列表上进行迭代,但使用迭代器在内存使用方面非常优化。因为每次您想要更改元素时,您都必须(最终)遍历序列并替换要修改的元素。在遍历结果之前,每次更改都会有一个迭代器-这可能会消耗大量内存,具体取决于需要做的更改。耶,bytearray:^)请注意,
bytearray(248956422)
也做同样的事情。如果内存有问题(因为这会分配内存),OP可以使用a并将值视为int;这将是缓慢的,但不是内存饥饿。
def anno(*args):
    for idx in xrange(248956422):
        elm = "0"

        for st, end, tag in args:
             for j in range(0, len(st)):
                 if st <= idx < end[j]:
                      elm = tag

        yield tag
 for tag in anno((whole_st_gen, whole_end_gen, "1"),
                 (whole_st_ex, whole_end_ex, "2")):
     write_to_file(tag)