我们在平时处理列表和字典的时候,有时候希望创建一个列表或者字典的副本拿出来使用,但是同时我们也不希望列表(字典)和其列表(字典)副本还保留着某种联系的时候, 比如说我们在修改列表的时候副本也跟着同步被修改了, 这是我们最不想看到的情况, 这种情况下我们该怎么处理呢?
接下来我们跟着代码块来进行学习了解
😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀
# 这里我们创建了一个函数传入目标的名称和目标对象, 返回目标的名称,内容及其id(内存地址)
def information(name, content):
"""
:param name: 目标的名称
:param content: 目标的内容
:return: 返回目标的id信息
"""
print(f" {name} 的内容为: {content} 同时其 id 值为: {id(content)}")
🐧🐧🐧🐧🐧🐧🐧🐧🐧🐧🐧🐧🐧🐧🐧🐧🐧🐧🐧🐧🐧🐧🐧🐧🐧🐧🐧🐧🐧
浅拷贝:copy()函数
# 我们创建了一个1到6数字组成的列表
number_first = [1, 2, 3, 4, 5, 6]
# 我们将 number_first 对象赋值给了 number_second
number_second = number_first
# 我们将 number_first 对象通过 copy()函数 浅拷贝给了我们 number_third (两种写法, 方法二要导入copy模块 import copy)
写法一: number_third = number_first.copy()
写法二: number_third = copy.copy(number_first)
# 对 number_first 进行修改操作, 比如在列表末尾添加数字 7
number_second.append(7)
# 调用我们之前创建的函数, 来查看我们的结果
information('number_first', number_first)
🐸🐸>>> number_first 的内容为: [1, 2, 3, 4, 5, 6, 7] 同时其 id 值为: 1513051403136
information('number_second', number_second)
🐸🐸>>> number_second 的内容为: [1, 2, 3, 4, 5, 6, 7] 同时其 id 值为: 1513051403136
information('number_third', number_third)
🐸🐸>>> number_third 的内容为: [1, 2, 3, 4, 5, 6] 同时其 id 值为: 1513051625280
结论:
🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻
这里 number_ first 简称 first 其他同理:
我们会发现 first 和 second 的 id(内存地址) 是一样的, 这说明什么问题呢, 就是我们 first 和 second 指向的是同一个列表对象: [1, 2, 3, 4, 5, 6] ,当我们不管是修改 first 还是 second 另一方都会进行着同步的修改----> 我们在second列表末尾添加7, first列表末尾也跟着添加了7 而我们使用浅拷贝copy()函数创建的 third 的末尾名没有添加7,它其他另外两个对象的 id地址指向不同 说明这个方法才是创建了一个真正我们想要的列表'副本'
🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻🐻
深度拷贝:deepcopy()函数
# 导入 copy 模块
import copy
# 这里我们创建一个由数字列表嵌套一个字母列表的列表
list_first = [['a', 'b', 'c', 'd'], 1, 2, 3, 4, 5, 6]
# 我们将 list_first 对象赋值给了 list_second
list_second = list_first
# 我们将 list_first 对象通过 copy()函数 浅拷贝给了我们 list_third
list_third = copy.copy(list_first)
# 我们将 list_first 对象通过 deepcopy()函数 深拷贝给了我们 list_fourth
list_fourth = copy.deepcopy(list_first)
# 这里我们对列表进行修改操作: 将 list_first 索引值为 1 处的数字 1 替换成为 字母 x
list_first[1] = 'x'
# 这里我们对列表内嵌套的列表进行修改: 将我们数字列表内的字母列表的第二个字母 b 替换为 e
list_first[0][1] = 'e'
information('list_first', list_first)
🐸🐸>>> list_first 的内容为: [['a', 'e', 'c', 'd'], 'x', 2, 3, 4, 5, 6] 同时其 id 值为: 2715690569792
information('list_second', list_second)
🐸🐸>>> list_second 的内容为: [['a', 'e', 'c', 'd'], 'x', 2, 3, 4, 5, 6] 同时其 id 值为: 2715690569792
information('list_third', list_third)
🐸🐸>>> list_third 的内容为: [['a', 'e', 'c', 'd'], 1, 2, 3, 4, 5, 6] 同时其 id 值为: 2715690568128
information('list_fourth', list_fourth)
🐸🐸>>> list_fourth 的内容为: [['a', 'b', 'c', 'd'], 1, 2, 3, 4, 5, 6] 同时其 id 值为: 2715690570432
结论:
🐯🐯🐯🐯🐯🐯🐯🐯🐯🐯🐯🐯🐯🐯🐯🐯🐯🐯🐯🐯🐯 🐯🐯🐯🐯🐯🐯🐯🐯
这里 list_ first 简称 first 其他同理:
根据上面浅复制所得的经验我们很容易就可以观察到, first 和 second 的 id 值是一样的,所以我们不管是修改了列表还是列表内嵌套的列表其值都会一起跟着变化
我们再仔细点观察会发现我们使用copy() 函数生成的third列表的最外层列表没有跟着修改,但是内部嵌套的列表还是被修改了, 所以我们可以得出 浅复制copy()函数可以保证我们生成的最外层列表的内容保持不变, 但是其内部嵌套的列表还是会跟着first列表的修改而发生变化
最后我们可以总结出: 如果要复制的列表包含了列表, 那就使用copy.deepcopy() 创建一个我们想要的 '列表副本' , 这样我们才算是真正创建了能独立于最初列表的真正列表副本
🐯🐯🐯🐯🐯🐯🐯🐯🐯🐯🐯🐯🐯🐯🐯🐯🐯🐯🐯🐯🐯 🐯🐯🐯🐯🐯🐯🐯🐯
以上就是我对深拷贝和浅拷贝的理解啦, 希望对你们有用的宝子, 动动小手点亮下方的小红心: