更改函数内列表中的全局列表

时间:2016-11-23 17:57:03

标签: python list recursion

我正在学习python列表和递归编码。我试图通过更改原始列表来压缩列表,而不是返回新列表。这是我到目前为止的输出

     >>> list1 = [3,4,[[5]]]
     >>> list2 = [[[1, 2, list1], (6, [7]), 8], 9, False]
     >>> flatten_in_place(list2)
     >>> list2
     [1, 2, 3, 4, 5, (6, [7]), 8, 9, False]
     >>> list1
     [3, 4, [[5]]]

正如您所看到的,我已经成功地平了一些list2,但是[3,4,[[5]]]仍然没有成功。我希望它成为[3,4,5]。

我的代码:

 def flatten(lst):

   if lst == []:
       return lst
   if type(lst[0]) ==  type(lst):
       return flatten(lst[0]) + flatten(lst[1:])
   return lst[:1] + flatten(lst[1:])

 def flatten_in_place(lst):


    if lst == []:
      lst
    if type(lst[0]) ==  type(lst):
      lst[:]  = flatten(lst[0]) + flatten(lst[1:])

    lst[:] = lst[:1] + flatten(lst[1:])

现在我想我应该为内部列表添加另一个递归,但我不知道如何做到这一点。

1 个答案:

答案 0 :(得分:0)

<已移除原始代码>

编辑回应评论。

然后,这将是棘手的。请注意,当您展平 list2 时,最终结果不再包含 list1 :我们现在有三个新元素--3,4,5 - 代替 list1的

然后,诀窍是依次考虑列表中的每个元素,首先在该元素上重复,替换任何列表元素,然后返回给调用者。

所以这是一个有效的解决方案。在每次调用时,它遍历列表,构建结果列表。输入列表的任何列表类型元素都被送到递归调用。

痛苦的部分是列表长度改变的情况,例如将2元素列表[1,[2,3]]转换为3元素列表[1,2,3]。要在不更改基础对象指针的情况下实现此更改,我需要分三步完成:

  1. 构建一个新列表,输入列表的扁平版本。
  2. 弹出原始列表中的所有元素;这会留下一个空列表,但在原始对象句柄下。
  3. 将结果列表的每个元素附加到原始列表。
  4. 这保留了原始列表的子元素的副作用。但是,请注意,在展平后仍然无法保持该关系:原始列表不再包含子列表;相反,它按顺序包含对子列表元素的新引用。

    def flatten_in_place(lst): 
    
        # print "ENTER in_place", lst
        result = []
        for i in range(len(lst)):
            if type(lst[i]) == type([]):
                result.extend(flatten_in_place(lst[i]))
            else: 
                result.append(lst[i])
            # print "Loop", i, "result =", result
    
        # print "After loop, lst =", lst
        for _ in range(len(lst)):
            lst.pop()
        for _ in range(len(result)):
            lst.append(result[_])
        # print "LEAVE in_place", lst
        return result
    
    
    list1 = [3, 4, [[5]]]
    list2 = [[[1, 2, list1], (6, [7]), 8], 9, False]
    flatten_in_place(list2)
    print ("list2 flattened", list2)
    # [1, 2, 3, 4, 5, (6, [7]), 8, 9, False]
    print ("list1 affected", list1)
    # [3, 4, 5]
    

    我会为学生或其他SO居民留下任何改进作为练习。