def divide(alist):
# when the list have only one element, it should return the 0
if len(alist) == 1:
alist[:] = list([0])
else:
middle = len(alist) / 2
divide(alist[:middle])
divide(alist[middle:])
temp = [1, 2, 3, 4, 5, 6]
divide(temp)
print temp
在我的函数中,在递归之后,我想得到[0, 0, 0, 0, 0, 0]
,但temp
仍然是[1, 2, 3, 4, 5, 6]
。我还使用alist[:] = list([0])
来确保重新分配alist。
为什么呢?参考文献有问题吗?
答案 0 :(得分:2)
您的代码不起作用slicing
因为divide(alist[:middle])
创建了一个新列表,所以alist
在第一次递归之后没有引用temp
不再。
return
结果更常见,而不是试图在调用参数中创建副作用,例如:
def divide(alist):
# when the list have only one element, it should return the 0
if len(alist) == 1:
return [0]
middle = len(alist) // 2
return divide(alist[:middle]) + divide(alist[middle:])
print(divide(temp))
# [0, 0, 0, 0, 0, 0]
显然,这是相对无稽之谈,但我假设您只是设置结构来执行特定的操作。
如果你真的想用副作用做这个(不推荐!!!)那么你需要保留left
和right
索引并使用它来最终分配{{1} },例如:
[0]
如果你想保留原始的调用签名,那么你可以使用def divide(alist, left, right):
middle = (right - left) // 2
# when the list have only one element, it should return the 0
if middle == 0:
alist[left:right] = [0]
else:
divide(alist, left, left+middle)
divide(alist, left+middle, right)
temp = [1, 2, 3, 4, 5, 6]
divide(temp, 0, len(temp))
print(temp)
# [0, 0, 0, 0, 0, 0]
函数来处理递归,这将允许你默认args,但实际上只有_inner()
没有它们:
return _inner(0, len(alist))
答案 1 :(得分:1)
下次提问时请提及您的目标。我的猜测是你不需要递归和就地修改你的列表。
所以我的第一个答案是提出就地修改而不递归:
def set_to_zero(alist):
alist[:] = [0 for _ in alist]
temp = [1, 2, 3, 4, 5, 6]
set_to_zero(temp)
print(temp)
# [0, 0, 0, 0, 0, 0]
事实证明,你需要递归而没有就地修改,因为你想写一个merge sort。
合并排序最常见的实现没有排序; [5] 因此,必须为输入分配输入的内存大小 要存储的已排序输出(请参阅下面的仅需要的版本 n / 2个额外空格)。
这里是一个clean implementation of the sort,带有一些调试行。这是一个关于SO(Mergesort python)的相关问题,有许多实现。