Python|赋值、浅拷贝与深拷贝

简介: Python|赋值、浅拷贝与深拷贝

赋值

python中一个变量可以说是内存中一个对象的‘标签’或者‘引用’。假设现在有一个变量a

a=1

a是指向了内存中的一个int型对象,a相当于一个指向该对象的标签,如果给a重新赋值:a=7

那么a将会移动,指向另一个int型对象。原来的对象a当没有任何标签或者引用指向它时,会被自动释放。

所以在python中,变量不用定义类型,也可以说是没有类型,类型是属于对象的而不是变量的,这就和javacc++等语言有很大的不同,在这些语言中要先声明变量类型,并且指定类型的变量只能放入该类型的内容。

因此,在python中,对对象的赋值都是对象的引用地址的传递(变量传递是传引用而不是传值)。

b=1

a=b

a is b #返回True

ab都指向同一个内存地址,反过来说该内存地址有两个标签,修改其中一个的变量的值将会引起另一个变量值的变化。

浅拷贝与深拷贝

先从概念上来区分浅拷贝与深拷贝。

浅拷贝与上文的赋值相似,只是换了一个标签(引用)(指向同一个内存地址),而不会重新开辟一个内存地址来存放相同的值,改变其中一个对象的值会引起另一个对象的值的变化。

深拷贝则是换一个标签(引用)并重新开辟一块内存来存放相同的值,因此内存地址也会改变,改变其中一个对象的值不会对另一个对象的值产生影响。

注意:python中,浅拷贝与深拷贝的不同仅仅是对组合对象而言,所谓的组合对象就是指包含其他对象的对象,比如列表、类等。而对于数字,字符串以及其他‘原子’类型,没有拷贝一说,产生的都是原对象的引用。

a=”abc”

b=copy.deepcopy(a) #深拷贝

a is b #返回True

下面通过组合对象来看看深拷贝与浅拷贝的区别

#浅拷贝

import copy

a=[11,’abc’,[‘python’,’nice’]]

b=copy.copy(a) #浅拷贝

a is b #返回False

print ( id (a) , id (b) ) #返回ab内存地址,不相同

a[0] is b[0] #返回True

print ( id (a[0]) , id (b[0]) ) #返回a[0]b[0]内存地址,相同

浅拷贝会创造一个新的对象,上述例子中“a is not b”。但是对于对象中的元素,则使用元素的引用,也就是“a[i] is b[i]”。

a[0]=51

b[0] is a[0] #返回False

a[1]=”py”

b[1] is a[1] #返回False

a[2].append('yes')

a[2] is b[2] #返回True

由于该对象中的第一个元素和第二个元素都是不可变类型,当修改不可变类型时会产生新的对象并使用一个新的内存地址,而b仍然指向未修改前的地址,所以会返回False。第三个元素是可变类型,修改操作不会产生新的对象,所以a的变化会引起b的变化。

常见的浅拷贝操作:切片操作、工厂函数(list/dir/set)copy函数。

#深拷贝

import copy

a=[11,’abc’,[‘python’,’nice’]]

b=copy.deepcopy(a) #深拷贝

a is b #返回False

a[0] is b[0] #返回False

print ( id (a) , id (b) ) #返回ab内存地址,不相同

print ( id (a[0]) , id (b[0]) ) #返回a[0]b[0]内存地址,不相同

跟浅拷贝类似会创造一个新的对象,所以a is not b。但是对于其中的元素,深拷贝都会生成一份相同的,并使用不同的内存地址储存,所以a[0] is not b[0]

 

目录
相关文章
|
13天前
|
索引 Python
Python 列表切片赋值教程:掌握 “移花接木” 式列表修改技巧
本文通过生动的“嫁接”比喻,讲解Python列表切片赋值操作。切片可修改原列表内容,实现头部、尾部或中间元素替换,支持不等长赋值,灵活实现列表结构更新。
89 1
|
10月前
|
Python
[oeasy]python055_python编程_容易出现的问题_函数名的重新赋值_print_int
本文介绍了Python编程中容易出现的问题,特别是函数名、类名和模块名的重新赋值。通过具体示例展示了将内建函数(如`print`、`int`、`max`)或模块名(如`os`)重新赋值为其他类型后,会导致原有功能失效。例如,将`print`赋值为整数后,无法再用其输出内容;将`int`赋值为整数后,无法再进行类型转换。重新赋值后,这些名称失去了原有的功能,可能导致程序错误。总结指出,已有的函数名、类名和模块名不适合覆盖赋新值,否则会失去原有功能。如果需要使用类似的变量名,建议采用其他命名方式以避免冲突。
144 14
|
9月前
|
存储 Python
[oeasy]python056_python中下划线是什么意思_underscore_理解_声明与赋值_改名字
在Python中,下划线有多种用途。单下划线(_)常用于避免命名冲突,如将`max`改为`max_`以保留内置函数功能。双下划线(__var__)通常用于特殊方法和属性,如`__name__`、`__doc__`等。此外,单下划线(_)在交互式解释器中表示上一次表达式的值,但不建议作为普通变量名使用。总结:下划线用于避免命名冲突及特殊标识。
175 1
|
10月前
|
Python 容器
[oeasy]python048_用变量赋值_连等赋值_解包赋值_unpack_assignment _
本文介绍了Python中变量赋值的不同方式,包括使用字面量和另一个变量进行赋值。通过`id()`函数展示了变量在内存中的唯一地址,并探讨了变量、模块、函数及类类型的地址特性。文章还讲解了连等赋值和解包赋值的概念,以及如何查看已声明的变量。最后总结了所有对象(如变量、模块、函数、类)都有其类型且在内存中有唯一的引用地址,构成了Python系统的基石。
125 5
|
11月前
|
存储 Python 容器
[oeasy]python045_[词根溯源]赋值_assignment_usage_使用
本文回顾了上一次讲解的内容,重点讨论了变量的概念及其在各种系统和游戏中的应用。文章详细解释了变量的声明与赋值操作,强调了赋值即为将具体值存储到变量名下的过程。同时,通过例子说明了字面量(如数字0)不能被赋值给其他值的原因。此外,还探讨了“赋值”一词的来源及其英文表达“assignment”的含义,并简要介绍了与之相关的英语词汇,如sign、assign、signal等。最后,总结了本次课程的核心内容,即赋值操作的定义和实现方式。
120 3
|
11月前
|
Python
Python赋值运算符
Python赋值运算符。
111 2
|
API 开发者 索引
Python中的省略号(Ellipsis)赋值方式
在Python中,省略号(`...`)是一种特殊对象,称为Ellipsis,虽不常用但在特定场景下非常实用,如函数占位、未实现方法示例及NumPy数组处理。本文通过示例介绍`a = ...`的用法。省略号类似于`None`,可用作代码结构的占位符,保持代码完整性和可读性,同时在API设计中标识待实现的方法。特别是在NumPy中,省略号用于表示多维数组的剩余维度,简化数组操作,提高代码灵活性和可读性。掌握这一技巧有助于提升Python编程能力。
347 1
|
存储 Java 编译器
Python学习三:学习python的 变量命名规则,算数、比较、逻辑、赋值运算符,输入与输出。
这篇文章是关于Python编程语言中变量命名规则、基本数据类型、算数运算符、比较运算符、逻辑运算符、赋值运算符以及格式化输出与输入的详细教程。
226 0
Python学习三:学习python的 变量命名规则,算数、比较、逻辑、赋值运算符,输入与输出。
|
数据处理 Python
python变量重新赋值
【8月更文挑战第4天】
408 6
|
API Python
python中copy模块的使用,深拷贝和浅拷贝
python中copy模块的使用,深拷贝和浅拷贝
303 0

推荐镜像

更多