【NB】Python 中变量赋值传递时的引用和拷贝

1769176   ·   发表于 2021-3-16   ·   编程代码

曾经看到这样一个问题,一个字典中的元素是列表,将这个列表元素赋值给一个变量,然后修改这个列表中元素的值,结果发现,字典中那个列表也同样修改了。

那个问题如下:
dict = {'a':[1,2,3,4,5],'b':2}
x = dict['a']
for i in range(5):
x[i] = 0
print(dict['a'])
20 Reply   |  Until 2021-3-17 | 3197 View

py2815
发表于 2021-3-16

程序运行结果如下:

评论列表

  • 加载数据中...

编写评论内容

menglicl
发表于 2021-3-16

[0, 0, 0, 0, 0]
这儿涉及到Python赋值到底是引用还是拷贝一份的问题,即赋值时是传值还是传址。上面问题是将"a"的值赋给了x出现了上述情况,如果是将"b"的值赋给了x,当我们修改x的值时,字典dict的值并不受影响。

评论列表

  • 加载数据中...

编写评论内容

1797591992
发表于 2021-3-16

>>> dict = {'a':[1,2,3,4,5],'b':2}
>>> x = dict['b']
>>> x
2
>>> x=x+3
>>> x
5
>>> dict
{'a': [1, 2, 3, 4, 5], 'b': 2}
>>>

评论列表

  • 加载数据中...

编写评论内容

yuforum
发表于 2021-3-16

那么问题来了,变量赋值传递时什么情况下是传值(拷贝),什么情况下是传址(引用)呢?

评论列表

  • 加载数据中...

编写评论内容

呸友
发表于 2021-3-16

1、直接拷贝

评论列表

  • 加载数据中...

编写评论内容

edream
发表于 2021-3-16

当我们不知道是引用还是拷贝的情况下,可以显式的拷贝。比如字典对象本身都具有拷贝的方法:
x=dict.copy()

评论列表

  • 加载数据中...

编写评论内容

q4041121
发表于 2021-3-16

没有拷贝方法的对象,也是可以拷贝的。这儿我们引入一个深拷贝的概念,深拷贝——即python的copy模块提供的一个deepcopy方法。深拷贝会完全复制原变量相关的所有数据,在内存中生成一套完全一样的内容,在这个过程中我们对这两个变量中的一个进行任意修改都不会影响其他变量。

评论列表

  • 加载数据中...

编写评论内容

1789137592
发表于 2021-3-16

还是上面的代码,如果改成如下:

评论列表

  • 加载数据中...

编写评论内容

asdfkns
发表于 2021-3-16

import copy
dict = {'a':[1,2,3,4,5],'b':2}
x = copy.deepcopy(dict['a'])
for i in range(5):
x[i] = 0
print(dict['a'])

评论列表

  • 加载数据中...

编写评论内容

alpdr
发表于 2021-3-16

运行结果dict值不受影响。

评论列表

  • 加载数据中...

编写评论内容
LoginCan Publish Content