Python中l(wèi)ist列表的賦值方法及遇到問(wèn)題處理
問(wèn)題起源:
本文的原因是因?yàn)樵谑褂胠ist的直接賦值b=a時(shí),得到的結(jié)果與預(yù)期不同,后來(lái)才發(fā)現(xiàn)直接使用等于號(hào)=對(duì)列表進(jìn)行賦值會(huì)產(chǎn)生一系列的問(wèn)題,于是將賦值、淺拷貝、深拷貝三者之間的區(qū)別進(jìn)行記錄。
1.列表list賦值方法
在python中,對(duì)象的賦值就是簡(jiǎn)單的對(duì)象引用,這點(diǎn)和C++是不同的,
如下例子所示:
a = ['a', 'b', 'c'] b = a ? # 采用簡(jiǎn)單的=賦值 print(a==b) # 下面是輸出結(jié)果: True
上面這種情況下,b和a是一樣的,他們指向同一片內(nèi)存,b不過(guò)是a的別名,是引用。我們可以使用a與b是否相同來(lái)判斷,返回True,表明他們地址相同,內(nèi)容相同。
賦值操作(包括對(duì)象作為參數(shù)、返回值)不會(huì)開(kāi)辟新的內(nèi)存空間,它只是復(fù)制了新對(duì)象的引用。也就是說(shuō),除了b這個(gè)名字以外,沒(méi)有其它的內(nèi)存開(kāi)銷(xiāo)。
修改了a,就影響了b;同理,修改了b就影響了a。下面的例子嘗試對(duì)b進(jìn)行修改,在后面加入新的元素’d’,通過(guò)觀察輸出結(jié)果發(fā)現(xiàn):在修改列表b的同時(shí),列表a也會(huì)被修改,因?yàn)閮烧哂玫氖峭粋€(gè)內(nèi)存空間。
a = ['a', 'b', 'c']
b = a
b.append('d')
print('a = {}'.format(a))
print('b = {}'.format(b))
# 下面是輸出結(jié)果:
a = ['a', 'b', 'c', 'd']
b = ['a', 'b', 'c', 'd']2.淺拷貝(shallow copy)
淺拷貝會(huì)創(chuàng)建新對(duì)象,其內(nèi)容是原對(duì)象的引用。
淺拷貝有三種形式:切片操作,工廠函數(shù),copy模塊中的copy函數(shù)。
比如對(duì)上述a:
- 1、切片操作:b = a[:] 或者 b = [each for each in a]
- 2、工廠函數(shù):b = list(a)
- 3、copy函數(shù):b = copy.copy(a) #使用時(shí)要import copy模塊
淺拷貝產(chǎn)生的b不再是a了,使用is可以發(fā)現(xiàn)他們不是同一個(gè)對(duì)象,使用id查看,發(fā)現(xiàn)它們也不指向同一片內(nèi)存。但是當(dāng)我們使用 id(x) for x in a 和 id(x) for x in b 時(shí),可以看到二者包含的元素的地址是相同的。
在這種情況下,a和b是不同的對(duì)象,修改b理論上不會(huì)影響a。比如b.append([4,5])。
代碼效果如下:
a = ['a', 'b', 'c', ['yellow', 'red']]
b = a[:] ?# 采用了切片操作對(duì)列表b進(jìn)行賦值
b.append('green') # 對(duì)列表b執(zhí)行添加元素操作
print('a = {}'.format(a))
print('b = {}'.format(b))
# 下面是輸出結(jié)果:
a = ['a', 'b', 'c', ['yellow', 'red']] ?# a中的元素不發(fā)生變化
b = ['a', 'b', 'c', ['yellow', 'red'], 'green'] ?# b中增加了一個(gè)元素'green'但是要注意:淺拷貝之所以稱(chēng)為淺拷貝,是它僅僅只拷貝了一層,在a中有一個(gè)嵌套的list,如果我們修改了它,情況就不一樣了。
a[3].append(“blue”)。查看b,你將發(fā)現(xiàn)b也發(fā)生了變化。這是因?yàn)椋阈薷牧饲短椎膌ist。修改外層元素,會(huì)修改它的引用,讓它們指向別的位置,修改嵌套列表中的元素,列表的地址并為發(fā)生變化,指向的都是同一個(gè)位置。
代碼如下:
a = ['a', 'b', 'c', ['yellow', 'red']]
b = a[:] ?# 采用了切片操作對(duì)列表b進(jìn)行賦值
a[3].append('blue') ?# 在a列表中的第3個(gè)元素中增加元素'blue',由于a[3]本身也是一個(gè)列表,從而是在列表后增加了元素'blue',從輸出結(jié)果中可以看出來(lái)。
print('a = {}'.format(a))
print('b = {}'.format(b))
# 下面是輸出結(jié)果:
a = ['a', 'b', 'c', ['yellow', 'red', 'blue']]
b = ['a', 'b', 'c', ['yellow', 'red', 'blue']]3.深拷貝
深拷貝只有一種形式,copy模塊中的deepcopy函數(shù)。
和淺拷貝對(duì)應(yīng),深拷貝拷貝了對(duì)象的所有元素,包括多層嵌套的元素。因而,它的時(shí)間和空間開(kāi)銷(xiāo)要高。
同樣對(duì)la,若使用b = copy.deepcopy(a),再修改b將不會(huì)影響到a了。即使嵌套的列表具有更深的層次,也不會(huì)產(chǎn)生任何影響,因?yàn)樯羁截惓鰜?lái)的對(duì)象根本就是一個(gè)全新的對(duì)象,不再與原來(lái)的對(duì)象有任何關(guān)聯(lián)。
實(shí)例代碼如下:
import copy
a = ['a', 'b', 'c', ['yellow', 'red']]
b = copy.deepcopy(a) ? # 采用深拷貝對(duì)a進(jìn)行深拷貝操作
b.append('xyz')
print('a = {}'.format(a))
print('b = {}'.format(b))
# 下面是輸出結(jié)果:
a = ['a', 'b', 'c', ['yellow', 'red']] ? # 使用深拷貝,對(duì)b的修改不會(huì)影響到a
b = ['a', 'b', 'c', ['yellow', 'red'], 'xyz']或者用下面的代碼:
import copy
a = ['a', 'b', 'c', ['yellow', 'red']]
b = copy.deepcopy(a) ? # 采用深拷貝對(duì)a進(jìn)行深拷貝操作
a[3].append('crazy')
print('a = {}'.format(a))
print('b = {}'.format(b))
# 下面是輸出結(jié)果:
a = ['a', 'b', 'c', ['yellow', 'red', 'crazy']] ?
b = ['a', 'b', 'c', ['yellow', 'red']] ? # 對(duì)a的修改不會(huì)影響到b或者用下面的代碼:
import copy
a = ['a', 'b', 'c', ['yellow', 'red']]
b = copy.deepcopy(a) ? # 采用深拷貝對(duì)a進(jìn)行深拷貝操作
a[3].append('crazy')
b.append('dddd')
print('a = {}'.format(a))
print('b = {}'.format(b))
# 下面是輸出結(jié)果:
a = ['a', 'b', 'c', ['yellow', 'red', 'crazy']]
b = ['a', 'b', 'c', ['yellow', 'red'], 'dddd']4.關(guān)于拷貝操作的提醒
- 1、對(duì)于非容器類(lèi)型,如數(shù)字,字符,以及其它“原子”類(lèi)型,沒(méi)有拷貝一說(shuō)。產(chǎn)生的都是原對(duì)象的引用。
- 2、如果元組變量值包含原子類(lèi)型對(duì)象,即使采用了深拷貝,也只能得到淺拷貝。
到此這篇關(guān)于Python中list列表的賦值方法及遇到問(wèn)題處理的文章就介紹到這了,更多相關(guān)list列表賦值方法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
django的autoreload機(jī)制實(shí)現(xiàn)
這篇文章主要介紹了django的autoreload機(jī)制實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06
通過(guò)python獲取甲流分布數(shù)據(jù)
近期,多地學(xué)校出現(xiàn)因甲流導(dǎo)致的班級(jí)停課,兒科甲流患者就診量呈數(shù)倍增長(zhǎng),今天我們同樣的操作來(lái)獲取下現(xiàn)在甲流感染的數(shù)據(jù),需要的朋友可以參考下2023-03-03
pytorch學(xué)習(xí)教程之自定義數(shù)據(jù)集
這篇文章主要給大家介紹了關(guān)于pytorch學(xué)習(xí)教程之自定義數(shù)據(jù)集的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11
Python常用算法學(xué)習(xí)基礎(chǔ)教程
這篇文章主要學(xué)習(xí)Python常用算法,Python常用排序算法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一2017-04-04
Python pyecharts模塊安裝與入門(mén)教程
Echarts 是一個(gè)由百度開(kāi)源的數(shù)據(jù)可視化,憑借著良好的交互性,精巧的圖表設(shè)計(jì),得到了眾多開(kāi)發(fā)者的認(rèn)可,這篇文章主要介紹了Python pyecharts數(shù)據(jù)可視化模塊安裝與入門(mén)教程,需要的朋友可以參考下2022-09-09
Python中4種實(shí)現(xiàn)數(shù)值的交換方式
這篇文章主要介紹了Python中4種實(shí)現(xiàn)數(shù)值的交換方式,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-08-08

