在python中将,数据类型分为可变类型和不可变类型:
可变类型有:列表list,字典dict
不可变类型有:整形int、浮点型float、字符串string、元组tuple
当我们将一个数据作为形参传入函数时,如果在函数内修改形参,会发生一下情况:
- 当数据为不可变类型时,会生成一个新的对象,然后形参的标签指向新的对象,而实参的没有变
- 当数据为可变类型时,形参和实参都指向同一个对象,修改形参会直接在实参的基础上修改(即使是使用了copy()函数,在有些情况下依然会改变)
所以我们在写python函数时,传入字典要和传入数组一样注意,里面的值会在函数里进行修改,特别是在递归调用的时候,即便是使用copy()函数复制一样会修改,但depp_copy()函数可以解决这个问题。
值得注意的是,在函数中重新定义数据并不会改变实参的值,只有修改才会
举个例子:
def test_func(num):
num = {'a':2,'b':2}
def test_func_2(num):
num['a'] = 2
test_dict = {'a':1, 'b':2}
print('原字典:')
print(test_dict)
print('重新赋值字典后:')
test_func(test_dict)
print(test_dict)
print('修改字典后:')
test_func_2(test_dict)
print(test_dict)
结果:
可以看到对于字典而言,对形参重新复制并没有修改实参的值,但是修改形参却会影响到实参。
同时,对于copy()函数而言,由于一个变量很有可能不是指向一个完整的对象,所以变量的子元素依然会存在引用的清空。
举例:
import copy
def test_func_3(num):
new_num = num.copy()
new_num['c'] = 3
new_num['a']['b'] = 3
def test_func_4(num):
new_num = copy.deepcopy(num)
new_num['a']['b'] = 4
test_dict = {'a':{'b':1},'c':2}
print('原字典:')
print(test_dict)
print('copy()修改字典后:')
test_func_3(test_dict)
print(test_dict)
print(' deepcopy()修改字典后:')
test_func_4(test_dict)
print(test_dict)
结果:
可以看到使用copy()函数后,首先修改c的值没有成功,但是修改a中子字典b的值却成功了,说明使用copy()函数是复制了大的字典,而对于字字典没有复制
但deepcopy()函数解决了这个问题,完整地复制了整个字典,没有再修改实参。