Python for 迴圈中使用append()添加可變元素,前面的值被覆蓋,迴圈中記憶體應用地址不變

來源:互聯網
上載者:User

標籤:其他   添加   網上   對象   分配   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()添加可變元素,前面的值被覆蓋,迴圈中記憶體應用地址不變

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.