将列表指针传递给函数而不是列表

时间:2017-10-12 16:03:59

标签: python list recursion

是否可以将一个(移动)指针传递给一个列表启动到Python中的函数?

我有一个递归函数处理列表的一部分。列表本身没有改变,只有指向“起点”的指针。进去。我遇到的问题是长列表在内存溢出时杀死了代码。

以下是代码:

def trim(l):
    print("list len= ", len(l))
    if len(l)!= 1:
        trim(l[1:])
    else:
        print("done")

上面的例子是设计的,我的实际代码做的不仅仅是修剪列表,但它还有一个移动的启动指针。 100万个整数的列表在10G RAM机器上耗尽了内存。

欢迎任何想法。

3 个答案:

答案 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))

yieldgenerators有很好的解释 - What does the yield keyword do