用習(xí)慣了C的循環(huán),經(jīng)常因為循環(huán)修改list的值產(chǎn)生bug,主要就是循環(huán)是進(jìn)行淺拷貝的過程。
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

在對集合進(jìn)行遍歷的時候,為了節(jié)省空間,對于集合中的對象不會創(chuàng)建一個新的對象,如上圖的params,而是存儲該對象地址,所以對對象中的內(nèi)容的修改會直接影響到原集合。
但如果直接修改params,則不會造成原集合的變化。
關(guān)于賦值、淺拷貝、深拷貝
- 賦值:變量直接指向?qū)ο?/li>
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]
- 深拷貝:完全拷貝,不會對原變量產(chǎn)生影響
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]