python循環中對一個列表的賦值問題


參考:https://www.cnblogs.com/zf-blog/p/10613981.html

           https://www.cnblogs.com/andywenzhi/p/7453374.html?tdsourcetag=s_pcqq_aiomsg

 

python的賦值方式是數據建立內存單元,將數據存入內存,然后再將變量名指向存儲了數據的內存單元,如下圖示:

 

不同於c的賦值方式:先為變量分配內存,然后再將變量的數據存入內存。

為了節省內存,如果將一個變量的值賦值給另一個變量,比如,b = 3, a = b, 

 

 

 變量a和b有完全一致的ID(指向同一內存地址)。

由於上述機制的存在,實際上沒有為變量a分配內存,只是將a指向了變量b指向的內存地址。若對此不加注意,初學者就有可能出現感覺

很“怪異”的錯誤。比如有兩個列表:

x = [[2, 3]]
y = [[4, 5], [5, 6], [7, 8], [9, 10]]

 期望將y列表中的每個元素添加到x列表中組成新的列表z[i],所有的z[i]將組成新的列表:

z = 

[[[2, 3],[4, 5]],[[2, 3],[5, 6]],[[2, 3],[7, 8]],[[2, 3],[9, 10]]]

如果這樣編寫程序:

def list2list(list_a, list_b):
list_mix, len_e = [], len(list_b)
for j in range(len_e):
list_c = list_a
id(list_c)
id(list_a)
print("改變list_c賦值之前二者id:", id(list_c), id(list_a))
list_c.append(list_b[j])
id(list_c)
id(list_a)
print("改變list_c賦值之后二者id:", id(list_c), id(list_a))
list_mix.append(list_c)
return list_mix


x = [[2, 3]]
y = [[4, 5], [5, 6], [7, 8], [9, 10]]


if __name__ == '__main__':
z = list2list(x, y)
print(z)

 其輸出為:

改變list_c賦值之前二者id: 53391968 53391968
改變list_c賦值之后二者id: 53391968 53391968
改變list_c賦值之前二者id: 53391968 53391968
改變list_c賦值之后二者id: 53391968 53391968
改變list_c賦值之前二者id: 53391968 53391968
改變list_c賦值之后二者id: 53391968 53391968
改變list_c賦值之前二者id: 53391968 53391968
改變list_c賦值之后二者id: 53391968 53391968
[[[2, 3], [4, 5], [5, 6], [7, 8], [9, 10]], [[2, 3], [4, 5], [5, 6], [7, 8], [9, 10]], [[2, 3], [4, 5], [5, 6], [7, 8], [9, 10]], [[2, 3], [4, 5], [5, 6], [7, 8], [9, 10]]]

從中可以看出,無論有沒有對列表list_c的賦值進行添加更改,列表list_c和list_a的id都是完全一致的,這表明二者共用了內存地址。若對其中一個列表

list_c的賦值進行更改,則對應內存地址中的數據將更改,由於另一列表list_a與其共用數據內存,所以list_a的賦值也被“莫名其妙”地更改了,導致輸出

結果與預期大相徑庭。關鍵問題在於列表賦值更改方式(.append)。可對比下例:

def add02(a, b):
len_b = len(b)
d = []
for i in range(len_b):
c = a
print("c和a賦值更改前的id:", id(c), id(a))
c += 1
print("c和a賦值更改后的id:", id(c), id(a))
e = c + b[i]
d.append(e)
return d


x = 5
y = [6, 7, 8, 9, 10]


if __name__ == '__main__':
z = add02(x, y)
print(z)

輸出:

c和a賦值更改前的id: 259024032 259024032
c和a賦值更改后的id: 259024048 259024032
c和a賦值更改前的id: 259024032 259024032
c和a賦值更改后的id: 259024048 259024032
c和a賦值更改前的id: 259024032 259024032
c和a賦值更改后的id: 259024048 259024032
c和a賦值更改前的id: 259024032 259024032
c和a賦值更改后的id: 259024048 259024032
c和a賦值更改前的id: 259024032 259024032
c和a賦值更改后的id: 259024048 259024032
[12, 13, 14, 15, 16]

 

可將上文中list2list()改為:

def add_element(a, b):
c = a + b
return c


def list2list(list_b, list_e):
list_mix, len_e = [], len(list_e)
list_c = list_b * len_e
list_mix = list(map(add_element, list_c, list_e))
return list_mix


if __name__ == '__main__':
x = [[[2, 3]]]
y = [[[4, 5]], [[5, 6]], [[7, 8]], [[9, 10]]]
route = list2list(x, y)
print("route:", route)

輸出:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM