Python for 循環中使用append()添加可變元素,前面的值被覆蓋,循環中內存應用地址不變

在使用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的維度。 
相關文章
相關標籤/搜索