在使用list.append(a), 添加動態改變的a(a = random.random())時,發現循環中每一個新的循環改變的a會在list中把之前的值全部改變;
查找后自了,Python是基於對象引用的,append添加的是一個“地址、引用”,當這個地址內的內容改變時,前面的同“地址”的內容都改變。
查看“內存、應用”’使用 id(object).
簡單的就不啰嗦了網上關於地址內存都有介紹,經過測試后發現,一般情況下給變量 一個新值時這個id就會改變,當然這個值若是和以前
相同這個id就一樣。在for循環中這個情況就不一樣
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個結果,
但是
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()
結果
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在運行時又分配的新的地址、引用,所以前面的數值沒有變化。
說了怎么多還沒有到問題的重點;
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的維度。