在使用list.append(a), 添加動態改變的a(a = random.random())時,發現循環中每個新的循環改變的a會在list中把以前的值所有改變;app
查找後自了,Python是基於對象引用的,append添加的是一個「地址、引用」,當這個地址內的內容改變時,前面的同「地址」的內容都改變。dom
查看「內存、應用」’使用 id(object).測試
簡單的就不囉嗦了網上關於地址內存都有介紹,通過測試後發現,通常狀況下給變量 一個新值時這個id就會改變,固然這個值如果和之前spa
相同這個id就同樣。在for循環中這個狀況就不同code
import random def test(): return random.random() def test1(): for i in range(3): for i in range(2): a = test() print('a_id=',id(a))
結果是對象
a_id= 2566513744848 a_id= 2566513744872 a_id= 2566513744848 a_id= 2566513744872 a_id= 2566513744848 a_id= 2566513744872
能夠看到內存分配時,對應內層2次循環的給了2個2個地址,節省開支; 若是是這樣的話使用list.append()最後就只有6個元素2個結果,blog
可是內存
import random list_a = [] list = [1,2,3,4,5,6] def test(): return random.random() def test1(): for i in range(3): for i in range(2): a = test() print('a_id=',id(a)) list_a.append(a) print(list_a) test1()
結果io
a_id= 2566513744824 a_id= 2566513744848 a_id= 2566513744968 a_id= 2566513744992 a_id= 2566513745016 a_id= 2566513745040 [0.5481244502902065, 0.7452961787111314, 0.6038274060224955, 0.8269310521431017, 0.4091898711994284, 0.45233748625853376]
能夠看到地址都改變了,Python在運行時又分配的新的地址、引用,因此前面的數值沒有變化。for循環
說了怎麼多尚未到問題的重點;
import random list_a = [] list = [[1,1,0,1,0], [1,0,1,1,1]] def mutation(array): array.append(random.randint(1,10)) return array def test2(): for num in list: for i in range(3): a = mutation(num) print(a) print('a_id=',id(a)) list_a.append(a) print(list_a) test2()
[1, 1, 0, 1, 0, 8] a_id= 2566513576904 [1, 1, 0, 1, 0, 8, 10] a_id= 2566513576904 [1, 1, 0, 1, 0, 8, 10, 3] a_id= 2566513576904 [1, 0, 1, 1, 1, 3] a_id= 2566515364744 [1, 0, 1, 1, 1, 3, 5] a_id= 2566515364744 [1, 0, 1, 1, 1, 3, 5, 4] a_id= 2566515364744 [[1, 1, 0, 1, 0, 8, 10, 3], [1, 1, 0, 1, 0, 8, 10, 3], [1, 1, 0, 1, 0, 8, 10, 3], [1, 0, 1, 1, 1, 3, 5, 4], [1, 0, 1, 1, 1, 3, 5, 4], [1, 0, 1, 1, 1, 3, 5, 4]]
結果能夠看到我向list中添加了一個新的值,但在list中元素的改變並不會改變list的id,內層3個循環中list的id始終不變,
在加到list_a中的內層的3個循環中,始終是一個id,外層第一個循環結束後,取了此id的最後一個值,因此最後list_a的前3個值都相同。
實際上網上一個list里加字典例子和這個道理是同樣的,雙層循環的內存循環了不改變id的對象,
只是我寫的時候把list變成其餘形式瞭如([sum(list),,,]),找緣由時也就看了id和轉換的結果發現好多結果都同樣,
被其餘的好多猜錯試的好多,找了很久才發現緣由。
解決這個問題的辦法是用copy,在
mutation(array) 中copy要return的array產生一個新的id,(array = copy.copy(array)),至因而用淺拷貝仍是深拷貝就要看array的維度。