我正在学习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:])
现在我想我应该为内部列表添加另一个递归,但我不知道如何做到这一点。
答案 0 :(得分:0)
编辑回应评论。
然后,这将是棘手的。请注意,当您展平 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居民留下任何改进作为练习。