是否可以将一个(移动)指针传递给一个列表启动到Python中的函数?
我有一个递归函数处理列表的一部分。列表本身没有改变,只有指向“起点”的指针。进去。我遇到的问题是长列表在内存溢出时杀死了代码。
以下是代码:
def trim(l):
print("list len= ", len(l))
if len(l)!= 1:
trim(l[1:])
else:
print("done")
上面的例子是设计的,我的实际代码做的不仅仅是修剪列表,但它还有一个移动的启动指针。 100万个整数的列表在10G RAM机器上耗尽了内存。
欢迎任何想法。
答案 0 :(得分:2)
如果您正在编写非尾调用递归函数来迭代列表,那么您的问题更可能是堆栈溢出或与堆栈大小相关的内存不足错误。
我建议使用整数指针和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]
从您的代码中不清楚它实际上是做什么的。如果您尝试实际返回序列,那么您可能需要查看生成器,它不需要在内存中保存整个序列。
答案 1 :(得分:2)
难道你不能只传递索引而不是传递整个新列表吗?
因此,您可以调用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")
答案 2 :(得分:0)
处理大数据时,请使用生成器而不是常规迭代器。
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
有很好的解释 - What does the yield keyword do