python-列表变量未在递归中存储正确的结果 [英] python - list variable not storing proper result in recursion

查看:45
本文介绍了python-列表变量未在递归中存储正确的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过递归存储列表的所有可能的括号.

I am trying to store all possible parenthesisation of a list through recursion.

示例: printRange(0,3)答案将是 [[0],[1],[2]],[[0],[1、2]],[[0、1],[2]],[[0、12]]

当我尝试在功能旁边打印它时,我可能会得到正确的答案.当我尝试存储结果并在未获得所需结果后打印时,我会得到正确的答案.

I could get a right answer when i tried to print it in side the function.When i try to store the result and print it after i am not getting the desired result.

代码如下:

res=[]
def printRange(st,size,cans=[]):


    if(st==size):
        res.append([]+cans)
        print cans

    l=[]

    for i in range(st,size):
        l.append(i)
        tmp=[]+cans
        tmp.append(l)
        printRange(i+1,size,[]+tmp)

printRange(0,3)
print res

当我运行上面的代码时,我得到了:

When i run the above code i got:

[[0], [1], [2]]

[[0], [1, 2]]

[[0, 1], [2]]

[[0, 1, 2]]

[[[0, 1, 2], [1, 2], [2]], [[0, 1, 2], [1, 2]], [[0, 1, 2], [2]], [[0, 1, 2]]]

为什么res变量没有存储预期的结果?

why res variable is not storing the intended result?

推荐答案

之所以会这样,是因为 cans 是列表的列表,而这些内部列表会发生变异.您需要在 res 上附加 cans 的深层副本,即制作内部列表副本的副本.您可以使用 copy 模块中的 deepcopy 进行此操作,或者只编写适用于列表列表的简单Deepcopy.

This is happening because cans is a list of lists, and those inner lists get mutated. You need to append a deep copy of cans to res, i.e. a copy that makes copies of the internal lists. You can do that with deepcopy from the copy module, or just write a simple deepcopy that works for a list of lists.

这是代码的修复版本.

#from copy import deepcopy

def deepcopy(list2d):
    return [u[:] for u in list2d]

res = []
def printRange(st, size, cans=[]):
    if(st == size):
        res.append(deepcopy(cans))
        print cans

    l = []
    for i in range(st, size):
        l.append(i)
        tmp = [] + cans
        tmp.append(l)
        printRange(i+1, size, tmp)

printRange(0, 4)
print res

输出

[[0], [1], [2], [3]]
[[0], [1], [2, 3]]
[[0], [1, 2], [3]]
[[0], [1, 2, 3]]
[[0, 1], [2], [3]]
[[0, 1], [2, 3]]
[[0, 1, 2], [3]]
[[0, 1, 2, 3]]
[[[0], [1], [2], [3]], [[0], [1], [2, 3]], [[0], [1, 2], [3]], [[0], [1, 2, 3]], [[0, 1], [2], [3]], [[0, 1], [2, 3]], [[0, 1, 2], [3]], [[0, 1, 2, 3]]]


请注意,使用列表或其他可变对象作为默认参数通常不是一个好主意,因为默认参数是在定义函数时(而不是在调用函数时)分配的,这可能会导致令人惊讶的行为.它实际上并不会给您的代码造成问题,但是避免使用默认的可变参数仍然是一个好主意,除非您需要有趣"的行为,例如,因此可以将其用作备注缓存,即使如此,您也应该使用注释解释您是故意这样做的.:)请参见最小惊讶"和可变默认参数以了解更多信息详细信息.


Note that it's generally not a good idea to use a list or other mutable object as a default argument because default arguments are assigned when the function is defined, not when it's called, and that can cause surprising behaviour. It doesn't actually cause problems for your code, but it's still a good idea to avoid default mutable args unless you need that "interesting" behaviour, eg so it can be used as a memoization cache, and even then you should use a comment explaining that you're doing it on purpose. :) See "Least Astonishment" and the Mutable Default Argument for further details.


我将以一种略有不同的方式处理此任务,并使用我最喜欢的玩具"之一:递归 输出

[[0], [1], [2], [3]]
[[0], [1], [2, 3]]
[[0], [1, 2], [3]]
[[0], [1, 2, 3]]
[[0, 1], [2], [3]]
[[0, 1], [2, 3]]
[[0, 1, 2], [3]]
[[0, 1, 2, 3]]

如果您确实希望包含所有结果的列表,只需将生成器传递给 list 构造函数即可:

If you do actually want a list containing all the results, just pass the generator to the list constructor:

res = list(brackets(2))
print res

输出

[[[0], [1], [2]], [[0], [1, 2]], [[0, 1], [2]], [[0, 1, 2]]]

这篇关于python-列表变量未在递归中存储正确的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆