標籤:其他 添加 網上 對象 分配 for迴圈 深拷貝 random 迴圈
在使用list.append(a), 添加動態改變的a(a = random.random())時,發現迴圈中每一個新的迴圈改變的a會在list中把之前的值全部改變;
尋找後自了,Python是基於對象引用的,append添加的是一個“地址、引用”,當這個地址內的內容改變時,前面的同“地址”的內容都改變。
查看“記憶體、應用”’使用 id(object).
簡單的就不囉嗦了網上關於地址記憶體都有介紹,經過測試後發現,一般情況下給變數 一個新值時這個id就會改變,當然這個值若是和以前
相同這個id就一樣。在for迴圈中這個情況就不一樣
import randomdef 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= 2566513744848a_id= 2566513744872a_id= 2566513744848a_id= 2566513744872a_id= 2566513744848a_id= 2566513744872
可以看到記憶體配置時,對應內層2次迴圈的給了2個2個地址,節省開支; 如果是這樣的話使用list.append()最後就只有6個元素2個結果,
但是
import randomlist_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()
結果
a_id= 2566513744824a_id= 2566513744848a_id= 2566513744968a_id= 2566513744992a_id= 2566513745016a_id= 2566513745040[0.5481244502902065, 0.7452961787111314, 0.6038274060224955, 0.8269310521431017, 0.4091898711994284, 0.45233748625853376]
可以看到地址都改變了,Python在運行時又分配的新的地址、引用,所以前面的數值沒有變化。
說了怎麼多還沒有到問題的重點;
import randomlist_a = []list = [[1,1,0,1,0], [1,0,1,1,1]]def mutation(array): array.append(random.randint(1,10)) return arraydef 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的維度。
Python for 迴圈中使用append()添加可變元素,前面的值被覆蓋,迴圈中記憶體應用地址不變