Python 函数参数不是深度复制

标签 python python-3.x

我有两个相同的函数,但为不同的值设置值,看起来像

indices = [x for x in range(26)]
reflector = [0 for x in range(26)]
wiring = [0 for x in range(26)]

def generate_r(ind=indices,rf=reflector):
    while len(ind) > 0:
        smp = sample(ind, 2)
        for elt in smp:
            ind.remove(elt)
        rf[smp[0]] = smp[1]
        rf[smp[1]] = smp[0]

    return rf

def generate_w(ind=indices,wr=wiring):
    while len(ind) > 0:
        smp = sample(ind, 2)
        for elt in smp:
            ind.remove(elt)
        wr[smp[0]] = smp[1]
        wr[smp[1]] = smp[0]
        print(wr)
    return wr

我早就料到了

generate_r()
generate_w()

返回给我两个包含 0 到 25 之间的 26 个不同值的列表。但是,我发现反射器是我想要的列表,而 w 仍然是一个全 0 的列表。

经过检查,我发现运行 generate_r() 后索引为空,这让我认为 python 没有将索引的副本传递给我的函数,而是传递对同一对象的引用。这是怎么回事?如果是这样,有没有办法让函数的本地命名空间无需在函数本身内创建就可以获取自己的副本?

最佳答案

furas已经为您提供了解决方案。以下是它发生的原因。

>>> def increment(n):
...   n.append([4])
>>> L = [1, 2, 3]
>>> increment(L)
>>> print(L)
L = [1, 2, 3, 4]   # a changed!

代码 L = [1, 2, 3] 有变量 L 引用包含对三个不可变对象(immutable对象)的引用的列表对象:整数 1、2 和3.

enter image description here

像往常一样,当我们将 L 传递给 increment() 时,该函数的局部变量 nL:

enter image description here

.append() 方法就地修改列表,因为列表是可变的:

enter image description here

由于没有创建新对象并且更改发生在对象的位置,当我们打印 L 时,我们得到修改后的列表。

关于Python 函数参数不是深度复制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56895875/

相关文章:

python-3.x - 如何从 try_all_threshold 中自动选择最佳结果?

python - 在 Python 中,两个或多个连续的成员运算符按什么顺序处理?

python - 如何调用 json 字典中列表中的值

python-3.x - 将 image_to_osd 方法与 pytesseract 结合使用时出错

python - 如何在此服务器中实现 Websocket 握手?

python - C++ 到 numpy 再回到 C++,元组 PyObject

python - 从输出日志文件中排除 ANSI 转义序列

python - Django - 如何使用 URL 中定义的外键创建 POST?

python - 无法从函数返回值

python - 通过比较列表和字符串中的值创建一个新列表