python for循環(huán)中的淺拷貝

用習(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]
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容