首页 > 解决方案 > 按值复制变量而不是引用

问题描述

对 python 来说相当新,并且努力实现变量的值副本。有一种算法可以递归调用另一个但没有得到所需的值,因为我认为在以下代码中将一个变量分配给另一个变量时使用了引用:

def search(problem, strategy, depthl, depthi, pruning):
    depthact = depthi
    sol = None
    while(not sol and depthact <= depthl):
        sol = limSearch(problem, strategy, depthact, pruning)
        depthact += depthi
    return sol

我想在depthact中具有与depthi相同的值,但我认为我指向相同的内存位置,因此在调用limSearch时,我使用传递给depthi中的方法的任何值而不是另一个我想使用,因为我然后增加它。

我对吗?任何帮助都感激不尽。

编辑:我知道 limSearch 算法的解决方案是在 depth=35 但希望这个其他算法检查解决方案是否存在给定的深度增量,所以,如果我用 depthl=40 和 depthi 调用搜索,它应该运行 limSearch 首先传入值 2,然后是 4、6、8、10 .. 直到它达到 36,然后它应该找到它在 35 中的解决方案原因,但它不起作用,而是得到一个 sol=在所有情况下都没有,就好像我用其他值调用 limSearch 一样。

def 搜索(问题、策略、40、2、修剪):

我希望像这样的调用在调用 limSearch 的循环中,直到它达到该算法中的解决方案,在这种情况下深度 = 35。所以我的预期结果是:

sol = limSearch(问题,策略,2,修剪)

sol = limSearch(问题,策略,4,修剪)

sol = limSearch(问题,策略,6,修剪)

...

sol = limSearch(问题,策略,36,修剪)

在这最后一次迭代中, sol 不会是 none,然后 while 循环将不再执行,返回我想要的解决方案。

我调用此函数的上下文如下:

if(strategy == 3): sol = search(p, strategy, depthl, depthi, pruning)
else: sol = limSearch(p, strategy, depthl, pruning)

通过用户输入读取所有值后。

depthl = int(input('depth: '))-1
if(strategy == 3): depthi = int(input('depth increment: '))

标签: pythonvariablesreferencecopy

解决方案


通常,如果您对引用和复制数据有疑虑,复制模块将为您提供所需的细粒度复制控制。

copy.copy保证做一个“浅拷贝”,其中列表将包含对旧数据的引用,但将是一个新列表(或其他容器)。

copy.deepcopy将为您提供一个“深层副本”,其中元素本身将被复制。

但是在这种情况下,您有一个简单的类型int并且是不可变的,因此每当值更改时都会创建一个新实例。(它比不可变对象复杂一点,但关键是,如果您使用简单类型,则赋值运算符=不会修改您已分配的那些简单类型的其他实例。)

IE:

a = 42
b = a
b +=1
print(a)
print(b)

这将打印“42”和“43”,表明修改 b 不会修改 a。

如果您不复制泛型类型,则应该复制模块。任意类可以实现方法__copy____deepcopy__更多信息)来制作对象的副本,并且是确保按照用户期望的方式制作副本的最 Pythonic 方式。

编辑:对于那些会编辑帖子以删除我回复的第一人称声音的人;不要那样做。我回答 OP 而不是写技术期刊,可读性很重要。我接受我的回答是不正确的,但只是因为我建议在int不需要时使用类型构造函数(尽管结果是相同的,但它不是pythonic)。我在这里包含了一些关于不可变数据类型的内容,但我不认为说“int是不可变的”是一个足够的答案,因为显式比隐式更好。话虽如此,不可变类型和标准库copy模块的知识可能是最完整的回应。


推荐阅读