Python 将列表指针传递给函数而不是列表
在Python中是否可以将指向列表开头的指针(移动)传递到函数中 我有一个递归函数处理列表的一部分。列表本身没有改变,只有指向“起始点”的指针进入列表。我遇到的问题是长列表导致代码内存溢出 代码如下:Python 将列表指针传递给函数而不是列表,python,list,recursion,Python,List,Recursion,在Python中是否可以将指向列表开头的指针(移动)传递到函数中 我有一个递归函数处理列表的一部分。列表本身没有改变,只有指向“起始点”的指针进入列表。我遇到的问题是长列表导致代码内存溢出 代码如下: def trim(l): print("list len= ", len(l)) if len(l)!= 1: trim(l[1:]) else: print("done") 上面的例子是人为设计的,我的实际代码所做的工作不同于仅仅修剪列表
def trim(l):
print("list len= ", len(l))
if len(l)!= 1:
trim(l[1:])
else:
print("done")
上面的例子是人为设计的,我的实际代码所做的工作不同于仅仅修剪列表,但它也有一个移动的开始指针。在10G RAM机器上,100万个整数的列表耗尽了内存
欢迎您提出任何建议。如果您正在编写一个非尾部调用递归函数来迭代列表,那么您的问题很可能是堆栈溢出,或者与堆栈大小相关的内存不足错误 我建议使用整数指针和for循环重新编写,因为Python似乎没有尾部调用优化 以下是您可能想要做的猜测:
x = [0,0,0,0,0,1,2,3,4]
def trim_leading_zero(l):
the_len = len(l)
start_i = 0
for i in xrange(the_len):
if l[i] != 0:
return l[i:]
>>> trim_leading_zero(x)
[1, 2, 3, 4]
从你的代码中不清楚它实际上要做什么。如果您试图实际返回一个序列,那么您可能需要查看生成器,它不需要在内存中保存整个序列。如果您正在编写一个非尾部调用递归函数来迭代列表,那么问题更可能是堆栈溢出,或者与堆栈大小相关的内存不足错误 我建议使用整数指针和for循环重新编写,因为Python似乎没有尾部调用优化 以下是您可能想要做的猜测:
x = [0,0,0,0,0,1,2,3,4]
def trim_leading_zero(l):
the_len = len(l)
start_i = 0
for i in xrange(the_len):
if l[i] != 0:
return l[i:]
>>> trim_leading_zero(x)
[1, 2, 3, 4]
从你的代码中不清楚它实际上要做什么。如果您试图实际返回一个序列,那么您可能需要查看生成器,它不需要在内存中保存整个序列。您不能只传递索引而不是传递整个新列表吗 因此,您可以调用
trim(l,0)
,然后根据列表的长度检查索引,然后根据需要调用trim(l,1)
def trim(l, idx):
print("list len = ", (len(l) - idx))
if idx < (len(x) - 1):
trim(l, idx + 1)
else:
print("done")
def微调(左、右):
打印(“列表长度=”,(长度(l)-idx))
如果idx<(透镜(x)-1):
配平(左,idx+1)
其他:
打印(“完成”)
你不能只传递索引而不是传递整个新列表吗
因此,您可以调用trim(l,0)
,然后根据列表的长度检查索引,然后根据需要调用trim(l,1)
def trim(l, idx):
print("list len = ", (len(l) - idx))
if idx < (len(x) - 1):
trim(l, idx + 1)
else:
print("done")
def微调(左、右):
打印(“列表长度=”,(长度(l)-idx))
如果idx<(透镜(x)-1):
配平(左,idx+1)
其他:
打印(“完成”)
处理大数据时,请使用生成器而不是常规迭代器
def trim(l):
print("list len= ", len(l))
pointer = 0
if len(l)!= 1:
yield l[pointer:]
pointer += 1
else:
print("done")
x = [1, 2, 3, 4, 5, 6, 7, 8, 9]
for i in trim(x):
print i
# [1, 2, 3, 4, 5, 6, 7, 8, 9]
生成器将一次生成一个项目,并允许您使用它执行任何需要的操作,避免在处理之前先创建整个列表。如果您想从中获取列表,只需执行list(trim(x))
这里有很多关于
yield
和generators
的解释-在处理大数据时,使用generators而不是常规迭代器
def trim(l):
print("list len= ", len(l))
pointer = 0
if len(l)!= 1:
yield l[pointer:]
pointer += 1
else:
print("done")
x = [1, 2, 3, 4, 5, 6, 7, 8, 9]
for i in trim(x):
print i
# [1, 2, 3, 4, 5, 6, 7, 8, 9]
生成器将一次生成一个项目,并允许您使用它执行任何需要的操作,避免在处理之前先创建整个列表。如果您想从中获取列表,只需执行list(trim(x))
这里有很多关于
yield
和generators
的解释-Python没有指针。您可以尝试传递索引,而不是创建副本的切片。还可以考虑使用<代码> NoMPy < /Cord>,它提供面向对象的原始数组,其中切片创建视图,而不是复制。还有内置的数组
模块,该模块提供大小为数字类型的节省空间的基本数组。这两种阵列方法都可以节省大量空间。1百万64位整数约为8兆字节。您可能会发现数据结构很有用。您可以使用l.popleft()
从deque的头部删除元素,而不是传递一个切片(这是所有元素的浅拷贝)。当l
是一个列表时,这不会产生l.pop(0)
的复制成本。Python没有指针。您可以尝试传递索引,而不是创建副本的切片。还可以考虑使用<代码> NoMPy < /Cord>,它提供面向对象的原始数组,其中切片创建视图,而不是复制。还有内置的数组
模块,该模块提供大小为数字类型的节省空间的基本数组。这两种阵列方法都可以节省大量空间。1百万64位整数约为8兆字节。您可能会发现数据结构很有用。您可以使用l.popleft()
从deque的头部删除元素,而不是传递一个切片(这是所有元素的浅拷贝)。当l
是一个列表时,这不会产生l.pop(0)
的复制成本。