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

Python 在函数内的列表中更改全局列表,python,list,recursion,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,

我正在学习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]]]
正如您所看到的,我成功地将列表2的一些部分适当地展平,但是[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:])
现在我想我应该为内部列表添加另一个递归,但我不知道怎么做

<原始代码已删除> 编辑以回应评论

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

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

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

其中最痛苦的部分是列表长度发生变化的情况,例如将2元素列表[1,2,3]]转换为3元素列表[1,2,3]。为了在不更改基本对象指针的情况下实现此更改,我分三个步骤进行工作:

构建一个新列表,即输入列表的展开版本。 从原始列表中弹出所有元素;这将留下一个空列表,但位于原始对象句柄下。 将结果列表的每个元素追加到原始列表中。 这将保留原始列表子元素的副作用。但是,请注意,在展平之后仍然无法保持这种关系:原始列表不再包含子列表;相反,它按顺序包含对子列表元素的新引用

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居民作为练习。

您发布的代码在语法上无效。你能把它清理干净让我们知道它在干什么吗?此外,尝试遵循SO准则,并尽可能将其最小化。如果没有使用三重引号中的代码,那么就不要包含它。递归测试依赖于它是一个列表-6,[7]是一个元组。您需要扩展您的测试以包括其他集合类型。可能是@AChampion的重复。它不是,现在我更新了代码,看看我想要更改什么。[3,4,[[5]]]到[3,4,5]这段代码仍然没有运行。未定义展平。当我将所有调用更改为“仅展平”时,当lst为空时会出现运行时错误。简而言之,您发布的代码不会重现问题。:/如果这就是问题所在,那么就太容易了,我不会问这个问题!我只想通过调用第一个来更改内部列表啊,哈!可以在这种情况下,问题是扁平化不会改变任何东西;更确切地说,它返回扁平化列表而不更改原始列表。谢谢,先生!!我还有一个问题,是否可以实现相同的功能而不返回?!当然,前提是您不依赖于该值。如果你注意到的话,我并没有在我的解决方案中实际使用它。