赞
踩
将列表中的值,拷贝到新的容器。
先思考一下,采用下列方式,是否能达到拷贝列表的目的?
nums = [1, 2, 3]
copied_nums = nums
print(f"nums={nums}")
print(f"copied_nums={copied_nums}")
代码输出:
nums=[1, 2, 3]
copied_nums=[1, 2, 3]
上述仅仅是,将copied_nums
变量与nums
变量都指向了相同的列表对象。如若不信,请查看下列代码:
nums = [1, 2, 3]
copied_nums = nums
copied_nums[2] = 1010
print(f"nums addr[0x{id(nums):x}], val:{nums}")
print(f"copied_nums addr[0x{id(copied_nums):x}], val:{copied_nums}")
代码输出:
nums addr[0x27968a65208], val:[1, 2, 1010]
copied_nums addr[0x27968a65208], val:[1, 2, 1010]
list对象构造
nums = [1, 2, 3]
copied_nums = list(nums) # list 对象构造方式
copied_nums[2] = 1010
print(f"nums addr[0x{id(nums):x}], val:{nums}")
print(f"copied_nums addr[0x{id(copied_nums):x}], val:{copied_nums}")
代码输出:
nums addr[0x1d53e2f5208], val:[1, 2, 3]
copied_nums addr[0x1d540189a88], val:[1, 2, 1010]
list生成表达式
nums = [1, 2, 3]
copied_nums = [num for num in nums] # list生成表达式
copied_nums[2] = 1010
print(f"nums addr[0x{id(nums):x}], val:{nums}")
print(f"copied_nums addr[0x{id(copied_nums):x}], val:{copied_nums}")
代码输出:
nums addr[0x14dd8165208], val:[1, 2, 3]
copied_nums addr[0x14dd8165408], val:[1, 2, 1010]
copy库
import copy
nums = [1, 2, 3]
copied_nums = copy.copy(nums) # copy库拷贝
copied_nums[2] = 1010
print(f"nums addr[0x{id(nums):x}], val:{nums}")
print(f"copied_nums addr[0x{id(copied_nums):x}], val:{copied_nums}")
代码输出:
nums addr[0x2329f3143c8], val:[1, 2, 3]
copied_nums addr[0x2329f2f9ac8], val:[1, 2, 1010]
若列表中嵌套列表,上述三种方式(浅拷贝)将不再可用。采用list对象构造方式,可自行尝试上述介绍的其他方式:
nums = [1, 2, 3, [4, 5, 6]]
copied_nums = list(nums) # list 对象构造方式
copied_nums[3][1] = 1010
print(f"nums addr[0x{id(nums):x}], val:{nums}")
print(f"copied_nums addr[0x{id(copied_nums):x}], val:{copied_nums}")
代码输出:
nums addr[0x29ec7dc5408], val:[1, 2, 3, [4, 1010, 6]]
copied_nums addr[0x29ec8149b48], val:[1, 2, 3, [4, 1010, 6]]
当然,可采用2层的for语句的方式,实现拷贝嵌套一层的列表。但是,如果是嵌套层级太深,那就需要太多的for语句,同时还依赖于每个列表成员的数据类型。
递归方式
def deep_copy_list(nums): ''' 仅支持int的列表成员和嵌套列表的拷贝 ''' items = [] for num in nums: if isinstance(num, int): items.append(num) else: items.append(deep_copy_list(num)) return items nums = [1, 2, 3, [4, 5, 6]] copied_nums = deep_copy_list(nums) # 递归调用拷贝函数 copied_nums[3][1] = 1010 print(f"nums addr[0x{id(nums):x}], val:{nums}") print(f"copied_nums addr[0x{id(copied_nums):x}], val:{copied_nums}")
代码输出:
nums addr[0x22f87b753c8], val:[1, 2, 3, [4, 5, 6]]
copied_nums addr[0x22f87ef95c8], val:[1, 2, 3, [4, 1010, 6]]
使用库函数
使用自定义的拷贝函数,需要比较完善的考虑,支持各种数据类型和列表的嵌套。不过,python中有提供现成的深拷贝库函数:
import copy
nums = [1, 2, 3, [4, 5, 6]]
copied_nums = copy.deepcopy(nums)
copied_nums[3][1] = 1010
print(f"nums addr[0x{id(nums):x}], val:{nums}")
print(f"copied_nums addr[0x{id(copied_nums):x}], val:{copied_nums}")
代码输出:
nums addr[0x15cad719c48], val:[1, 2, 3, [4, 5, 6]]
copied_nums addr[0x15cad719c88], val:[1, 2, 3, [4, 1010, 6]]
注:
一般情况下,仅用到浅拷贝;若使用到深拷贝,那表明程序框架需要再考虑。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。