python列表嵌套引發(fā)的問(wèn)題總結(jié)_第1頁(yè)
python列表嵌套引發(fā)的問(wèn)題總結(jié)_第2頁(yè)
python列表嵌套引發(fā)的問(wèn)題總結(jié)_第3頁(yè)
python列表嵌套引發(fā)的問(wèn)題總結(jié)_第4頁(yè)
全文預(yù)覽已結(jié)束

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第python列表嵌套引發(fā)的問(wèn)題總結(jié)目錄1.嵌套列表2.識(shí)別坑點(diǎn)3.區(qū)分兩個(gè)概念4.小例子5.正確代碼總結(jié)

1.嵌套列表

Python中有一種內(nèi)置的數(shù)據(jù)類型叫列表(list),它是一種容器,可以用來(lái)承載其他的對(duì)象(準(zhǔn)確的說(shuō)是其他對(duì)象的引用),列表中的對(duì)象可以稱為列表的元素,很明顯我們可以把列表作為列表中的元素,這就是所謂的嵌套列表。

嵌套列表可以模擬出現(xiàn)實(shí)中的表格、矩陣、2D游戲的地圖(如植物大戰(zhàn)僵尸的花園)、棋盤(如國(guó)際象棋、黑白棋)等。

2.識(shí)別坑點(diǎn)

在使用嵌套的列表時(shí)要小心,否則很可能遭遇非常尷尬的情況,下面是一個(gè)小例子:

defmain():

names=['關(guān)羽','張飛','趙云','馬超','黃忠']

subjs=['語(yǔ)文','數(shù)學(xué)','英語(yǔ)']

scores=[[0]*3]*5

forrow,nameinenumerate(names):

print('請(qǐng)輸入%s的成績(jī)'%name)

forcol,subjinenumerate(subjs):

scores[row][col]=float(input(subj+':'))

print(scores)

if__name__=='__main__':

main()

我們希望錄入5個(gè)學(xué)生3門課程的成績(jī),于是定義了一個(gè)有5個(gè)元素的列表,而列表中的每個(gè)元素又是一個(gè)由3個(gè)元素構(gòu)成的列表,這樣一個(gè)列表的列表剛好跟一個(gè)表格是一致的,相當(dāng)于有5行3列。

接下來(lái)我們通過(guò)嵌套的for-in循環(huán)輸入每個(gè)學(xué)生3門課程的成績(jī)。程序執(zhí)行完成后我們發(fā)現(xiàn),每個(gè)學(xué)生3門課程的成績(jī)是一模一樣的(尷尬),而且就是最后錄入的那個(gè)學(xué)生的成績(jī)。

3.區(qū)分兩個(gè)概念

要想把這個(gè)坑填平,我們首先要區(qū)分對(duì)象和對(duì)象的引用這兩個(gè)概念,而要區(qū)分這兩個(gè)概念,還得先說(shuō)說(shuō)內(nèi)存中的棧和堆。

我們經(jīng)常會(huì)聽(tīng)人說(shuō)起堆棧這個(gè)詞,但實(shí)際上堆和棧是兩個(gè)不同的概念。眾所周知,一個(gè)程序運(yùn)行時(shí)需要占用一些內(nèi)存空間來(lái)存儲(chǔ)數(shù)據(jù)和代碼,那么這些內(nèi)存從邏輯上又可以做進(jìn)一步的劃分。

對(duì)底層語(yǔ)言(如C語(yǔ)言)有所了解的程序員大都知道,程序中可以使用的內(nèi)存從邏輯上可以為五個(gè)部分,按照地址從高到低依次是:棧(stack)、堆(heap)、數(shù)據(jù)段(datasegment)、只讀數(shù)據(jù)段(staticarea)和代碼段(codesegment)。

棧用來(lái)存儲(chǔ)局部、臨時(shí)變量,以及函數(shù)調(diào)用時(shí)保存現(xiàn)場(chǎng)和恢復(fù)現(xiàn)場(chǎng)需要用到的數(shù)據(jù),這部分內(nèi)存在代碼塊開(kāi)始執(zhí)行時(shí)自動(dòng)分配,代碼塊執(zhí)行結(jié)束時(shí)自動(dòng)釋放,通常由編譯器自動(dòng)管理。

堆的大小不固定,可以動(dòng)態(tài)的分配和回收,因此如果程序中有大量的數(shù)據(jù)需要處理,這些數(shù)據(jù)通常都放在堆上,如果堆空間沒(méi)有正確的被釋放會(huì)引發(fā)內(nèi)存泄露的問(wèn)題,而像Python、Java等編程語(yǔ)言都使用了垃圾回收機(jī)制來(lái)實(shí)現(xiàn)自動(dòng)化的內(nèi)存管理(自動(dòng)回收不再使用的堆空間)。

4.小例子

所以,下面的代碼中,變量a并不是真正的對(duì)象,它是對(duì)象的引用,相當(dāng)于記錄了對(duì)象在堆空間的地址,通過(guò)這個(gè)地址我們可以訪問(wèn)到對(duì)應(yīng)的對(duì)象。

a=object()

b=['apple','pitaya','grape']

同理,變量b是列表容器的引用,它引用了堆空間上的列表容器,而列表容器中并沒(méi)有保存真正的對(duì)象,它保存的也僅僅是對(duì)象的引用。

知道了這一點(diǎn),我們可以回過(guò)頭看看剛才的程序,我們對(duì)列表進(jìn)行[[0]*3]*5操作時(shí),僅僅是將[0,0,0]這個(gè)列表的地址進(jìn)行了復(fù)制,并沒(méi)有創(chuàng)建新的列表對(duì)象。

所以,容器中雖然有5個(gè)元素,但是這5個(gè)元素引用了同一個(gè)列表對(duì)象。這一點(diǎn)可以通過(guò)id函數(shù)檢查scores[0]和scores[1]的地址得到證實(shí)。在此我們舉一個(gè)小例子,讀者朋友們可以敲一敲加深印象。

a=[[0]*3]*5id(a[0])

id(a[1])

#id相等

5.正確代碼

所以,正確的代碼應(yīng)該按照如下的方式進(jìn)行修改:

defmain():

names=['關(guān)羽','張飛','趙云','馬超','黃忠']

subjs=['語(yǔ)文','數(shù)學(xué)','英語(yǔ)']

scores=[[]]*5

forrow,nameinenumerate(names):

print('請(qǐng)輸入%s的成績(jī)'%name)

scores[row]=[0]*3#變?yōu)椴辉偾短?/p>

forcol,subjinenumerate(subjs):

scores[row][col]=float(input(subj+':'))

print(scores)

if__name__=='__main__':

main()

或者:

defmain():

names=['關(guān)羽','張飛','趙云','馬超','黃忠']

subjs=['語(yǔ)文','數(shù)學(xué)','英語(yǔ)']

scores=[[0]*3for_inrange(5)]

forrow,nameinenumerate(names):

print('請(qǐng)輸入%s的成績(jī)'%name)

scores[row]=[0]*3

forcol,subjinenumerate(subjs):

scores[row][col]=float(inpu

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論