Python中如何进行可变对象的引用赋值?

2026-05-17 01:021阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1173个文字,预计阅读时间需要5分钟。

Python中如何进行可变对象的引用赋值?

在使用Python列表时,若修改列表中的一项,其他项会联动变化。查阅文档后,在此记录:此现象因使用了赋值语句a=b,导致变量a和b指向同一内存地址。

在使用 Python 列表时, 出现了修改其中一个列表, 其他列表联动改变这个情况, 在查阅文档后, 写在这里记录一下.

出现这个情况的原因是因为我使用了 a = b 这个赋值语句, 我下意识的认为 a, b 是两个不同的对象, 其实在 Python 一切都是对象, 所谓的变量, 只是指向一个对象的内存地址. 我们平时使用的赋值语句 = 其实只是让一个一个变量指向另一个变量指向的内存地址. 例如:

a = 1 b = a print(a, b) print(id(a)) print(id(b)) a = 2 print(a, b)

1 1 140712422177856 140712422177856 2 1

可以看到两个变量指向同一个内存地址, 这是 Python 解释器为了节省内存资源, 选择的一种方式. 可以看到, 当变量指向不可变类型时候, b 的值并不会随着 a 的变化而变化.

然而这种方式有一个弊端, 当我们面对可变类型时, 就会发生一些不可控的事情.

a = [1, 2, 3] b = a print(a, b) print(id(a)) print(id(b)) a[0] = 4 print(a, b)

[1, 2, 3] [1, 2, 3] 2537876904712 2537876904712 [4, 2, 3] [4, 2, 3]

可以看到, 因为 a, b 两个变量指向的是同一个内存地址, 当我们修改 a 的数据时, b会一起改变. 常规情况下,这并不是我们想要的结果.

那么, 有没有办法把数据拷贝到一块新的内存地址中呢?

浅拷贝与深拷贝

这就需要用到 Python 内置库 copy. 我们需要用到这个库中的 copy, deepcopy 两个方法.

浅拷贝

我们使用 b = copy.copy(a) 进行浅拷贝, 执行这个语句后 a, b 是两个不同的对象, 指向不同的内存地址.

但是 a, b 中的子对象还是会指向同一地址, 例如下文中的 a 列表中的字典, b 列表中的字典就是子对象, 他们其实指向的是同一内存地址.

import copy a = [1, 2, 3, {'a': 1, 'b': 2, 'c': 3}] b = copy.copy(a) print(a) print(b) print(id(b)) print(id(a)) a[0] = 2 print(a) print(b)

[1, 2, 3, {'a': 1, 'b': 2, 'c': 3}] [1, 2, 3, {'a': 1, 'b': 2, 'c': 3}] 2537876907720 2537876907400 [2, 2, 3, {'a': 1, 'b': 2, 'c': 3}] [1, 2, 3, {'a': 1, 'b': 2, 'c': 3}]

可以看到, a, b 指向了不同的地址. 我们看下 a, b 中的子对象指向的内存地址

import copy a = [1, 2, 3, {'a': 1, 'b': 2, 'c': 3}] b = copy.copy(a) print(id(a[3])) print(id(b[3]))

2537876900904 2537876900904

可以看到, a, b 的子对象指向的内存. 因此, 当我们对这个字典进行操作时, 另一个数组对象中的也会随之变化, 原理同上.

那么, 有没有什么可以规避这一现象呢? 接下来我们走进深拷贝.

深拷贝

我们使用 b = copy.deepcopy(a) 进行深拷贝, 执行这个语句后 a, b 是两个不同的对象, 指向不同的内存地址. 且 a, b 的子对象也指向不同的内存地址, a, b 指向除了值相等, 完全没有任何关系的对象.

Python中如何进行可变对象的引用赋值?

import copy a = [1, 2, 3, {'a': 1, 'b': 2, 'c': 3, 'f': [1, 2, 3]}] b = copy.deepcopy(a) print(a) print(b) print(id(b)) print(id(a)) print(id(a[3])) print(id(b[3])) print(id(a[3]["f"])) print(id(b[3]["f"])) a[1] = 0 a[3]['d'] = 4 print(a) print(b)

[1, 2, 3, {'a': 1, 'b': 2, 'c': 3, 'f': [1, 2, 3]}] [1, 2, 3, {'a': 1, 'b': 2, 'c': 3, 'f': [1, 2, 3]}] 2537876918920 2537876918728 2537876851592 2537876851672 2537876916296 2537876919304 [1, 0, 3, {'a': 1, 'b': 2, 'c': 3, 'f': [1, 2, 3], 'd': 4}] [1, 2, 3, {'a': 1, 'b': 2, 'c': 3, 'f': [1, 2, 3]}]

可以看到, 不论对象嵌套有多少个子对象, 进行深拷贝后得到的对象及其子对象, 都指向不同的地址. 同样的, 对其中任何数据的修改都不会影响到另一个对象.

可以看到, Python 为了适应不同的需求, 为我们提供了非常灵活的方法, 可以根据需求灵活使用.

本文共计1173个文字,预计阅读时间需要5分钟。

Python中如何进行可变对象的引用赋值?

在使用Python列表时,若修改列表中的一项,其他项会联动变化。查阅文档后,在此记录:此现象因使用了赋值语句a=b,导致变量a和b指向同一内存地址。

在使用 Python 列表时, 出现了修改其中一个列表, 其他列表联动改变这个情况, 在查阅文档后, 写在这里记录一下.

出现这个情况的原因是因为我使用了 a = b 这个赋值语句, 我下意识的认为 a, b 是两个不同的对象, 其实在 Python 一切都是对象, 所谓的变量, 只是指向一个对象的内存地址. 我们平时使用的赋值语句 = 其实只是让一个一个变量指向另一个变量指向的内存地址. 例如:

a = 1 b = a print(a, b) print(id(a)) print(id(b)) a = 2 print(a, b)

1 1 140712422177856 140712422177856 2 1

可以看到两个变量指向同一个内存地址, 这是 Python 解释器为了节省内存资源, 选择的一种方式. 可以看到, 当变量指向不可变类型时候, b 的值并不会随着 a 的变化而变化.

然而这种方式有一个弊端, 当我们面对可变类型时, 就会发生一些不可控的事情.

a = [1, 2, 3] b = a print(a, b) print(id(a)) print(id(b)) a[0] = 4 print(a, b)

[1, 2, 3] [1, 2, 3] 2537876904712 2537876904712 [4, 2, 3] [4, 2, 3]

可以看到, 因为 a, b 两个变量指向的是同一个内存地址, 当我们修改 a 的数据时, b会一起改变. 常规情况下,这并不是我们想要的结果.

那么, 有没有办法把数据拷贝到一块新的内存地址中呢?

浅拷贝与深拷贝

这就需要用到 Python 内置库 copy. 我们需要用到这个库中的 copy, deepcopy 两个方法.

浅拷贝

我们使用 b = copy.copy(a) 进行浅拷贝, 执行这个语句后 a, b 是两个不同的对象, 指向不同的内存地址.

但是 a, b 中的子对象还是会指向同一地址, 例如下文中的 a 列表中的字典, b 列表中的字典就是子对象, 他们其实指向的是同一内存地址.

import copy a = [1, 2, 3, {'a': 1, 'b': 2, 'c': 3}] b = copy.copy(a) print(a) print(b) print(id(b)) print(id(a)) a[0] = 2 print(a) print(b)

[1, 2, 3, {'a': 1, 'b': 2, 'c': 3}] [1, 2, 3, {'a': 1, 'b': 2, 'c': 3}] 2537876907720 2537876907400 [2, 2, 3, {'a': 1, 'b': 2, 'c': 3}] [1, 2, 3, {'a': 1, 'b': 2, 'c': 3}]

可以看到, a, b 指向了不同的地址. 我们看下 a, b 中的子对象指向的内存地址

import copy a = [1, 2, 3, {'a': 1, 'b': 2, 'c': 3}] b = copy.copy(a) print(id(a[3])) print(id(b[3]))

2537876900904 2537876900904

可以看到, a, b 的子对象指向的内存. 因此, 当我们对这个字典进行操作时, 另一个数组对象中的也会随之变化, 原理同上.

那么, 有没有什么可以规避这一现象呢? 接下来我们走进深拷贝.

深拷贝

我们使用 b = copy.deepcopy(a) 进行深拷贝, 执行这个语句后 a, b 是两个不同的对象, 指向不同的内存地址. 且 a, b 的子对象也指向不同的内存地址, a, b 指向除了值相等, 完全没有任何关系的对象.

Python中如何进行可变对象的引用赋值?

import copy a = [1, 2, 3, {'a': 1, 'b': 2, 'c': 3, 'f': [1, 2, 3]}] b = copy.deepcopy(a) print(a) print(b) print(id(b)) print(id(a)) print(id(a[3])) print(id(b[3])) print(id(a[3]["f"])) print(id(b[3]["f"])) a[1] = 0 a[3]['d'] = 4 print(a) print(b)

[1, 2, 3, {'a': 1, 'b': 2, 'c': 3, 'f': [1, 2, 3]}] [1, 2, 3, {'a': 1, 'b': 2, 'c': 3, 'f': [1, 2, 3]}] 2537876918920 2537876918728 2537876851592 2537876851672 2537876916296 2537876919304 [1, 0, 3, {'a': 1, 'b': 2, 'c': 3, 'f': [1, 2, 3], 'd': 4}] [1, 2, 3, {'a': 1, 'b': 2, 'c': 3, 'f': [1, 2, 3]}]

可以看到, 不论对象嵌套有多少个子对象, 进行深拷贝后得到的对象及其子对象, 都指向不同的地址. 同样的, 对其中任何数据的修改都不会影响到另一个对象.

可以看到, Python 为了适应不同的需求, 为我们提供了非常灵活的方法, 可以根据需求灵活使用.