用习惯了C的循环,经常因为循环修改list的值产生bug,主要就是循环是进行浅拷贝的过程。
client_list = []
for i in range(0,10):
params = {}
params.update(
num = i,
name = 'a'
)
client_list.append(params)
for params in client_list:
params.update(
num = 0,
name = 'test'
)
temp_d = {}
temp_d['name'] = 'hello'
params = temp_d

在对集合进行遍历的时候,为了节省空间,对于集合中的对象不会创建一个新的对象,如上图的params,而是存储该对象地址,所以对对象中的内容的修改会直接影响到原集合。
但如果直接修改params,则不会造成原集合的变化。
关于赋值、浅拷贝、深拷贝
- 赋值:变量直接指向对象
ls = [i for i in range(0,10)] # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
lss = ls # [10, 10, 10, 10, 10, 10, 10, 10, 10, 10]
for idx,v in enumerate(lss):
lss[idx] = 10
lss # [10, 10, 10, 10, 10, 10, 10, 10, 10, 10]
ls # [10, 10, 10, 10, 10, 10, 10, 10, 10, 10]
- 浅拷贝:只拷贝父对象,不会拷贝对象中的子对象(而是引用地址)
ls = [[0,0,0], 1, 2, 3, 4, 5, 6, 7, 8, 9]
lss = ls.copy() # [[0,0,0], 1, 2, 3, 4, 5, 6, 7, 8, 9]
for idx in range(1,len(ls)):
lss[idx] = 10
lss[0].append(99)
ls # [[0, 0, 0], 1, 2, 3, 4, 5, 6, 7, 8, 9]
lss # [[0, 0, 0, 99], 10, 10, 10, 10, 10, 10, 10, 10, 10]
需要注意的是,
ls = [[0,0,0], 1, 2, 3, 4, 5, 6, 7, 8, 9]
lss = ls.copy() # [10, 10, 10, 10, 10, 10, 10, 10, 10, 10]
for idx in range(1,len(ls)):
lss[idx] = 10
# 这里又做了一次浅拷贝,所以不会影响值
for i in lss[0]:
i = 99
ls # [[0, 0, 0], 1, 2, 3, 4, 5, 6, 7, 8, 9]
lss # [[0, 0, 0], 10, 10, 10, 10, 10, 10, 10, 10, 10]
- 深拷贝:完全拷贝,不会对原变量产生影响
ls = [[0,0,0], 1, 2, 3, 4, 5, 6, 7, 8, 9]
lss = ls.copy() # [[0,0,0], 1, 2, 3, 4, 5, 6, 7, 8, 9]
for idx in range(1,len(ls)):
lss[idx] = 10
lss[0].append(99)
ls # [[0, 0, 0], 1, 2, 3, 4, 5, 6, 7, 8, 9]
lss # [[0, 0, 0, 99], 10, 10, 10, 10, 10, 10, 10, 10, 10]
网友评论