Python中的嵌套列表


主要參考的是Github上的一個項目:https://github.com/jackfrued/Python-100-Days
文章主要是對該項目中的內容進行學習 穿插一點自己的學習想法等內容~

嵌套列表

names = ['關羽', '張飛', '趙雲', '馬超', '黃忠']
courses = ['語文', '數學', '英語']
# 錄入五個學生三門課程的成績
# 錯誤 - 參考http://pythontutor.com/visualize.html#mode=edit
# scores = [[None] * len(courses)] * len(names)
scores = [[None] * len(courses) for _ in range(len(names))]
for row, name in enumerate(names):
    for col, course in enumerate(courses):
        scores[row][col] = float(input(f'請輸入{name}的{course}成績: '))
        print(scores)

該代碼的目的是為了構造一個names做行 courses做列的表格來記錄五個人的三門功課成績。
實際上即為構造一個5 × 3的二維數組。直接用循環造一個空的往里邊填數字也不是不行-_-

列表嵌套存在的意義就是簡化用循環去構造一個空列表的繁瑣代碼。

錯誤代碼

首先來看一下文中寫的那段錯誤的代碼~
scores = [[None] * len(courses)] * len(names)

自我分析

首先是一個空列表重復 len(courses) 次構成一個新列表,結果就是[[], [], []]
上述生成的列表再重復 len(names) 次,結果就是[[], [], []], [[], [], []], [[], [], []], [[], [], []], [[], [], []]?
是不是這個樣子哇.....

結果運行

只運行這三行代碼,結果顯示scores的內容如下:
[[None, None, None], [[None, None, None], [[None, None, None], [[None, None, None], [[None, None, None]]

None

且來科普一下None
None是一個特殊的常量,N必須大寫。它不表示0,不表示空字符串,表示沒有值(空值),數據類型是NoneType
空值與空對象不同,空值和占位符感覺差不多,知道這里應該有東西 但具體是什么不知道。空對象就是只定義了類型,里邊什么都不知道,有幾個等信息都不知道。
常用於assert、判斷以及函數無返回值的情況。例如使用print函數輸出數據,函數的返回值就是None。在不得不設置返回值的地方起到了一個占位作用。
Python函數中不寫返回值,默認返回None;最后只寫了return 同理。

揭秘

將分析語句變成兩個語句去執行

a = [[None] * len(courses)]
b = a * * len(names)

你會發現更改會對a和b同時生效,建立索引的時候你的列表行索引並沒有太大用處。操作就是找到列 然后修改那一列的所有元素。
實際上就是修改了列表a 然后重復列表a 表現在b中
所以這樣的嵌套是失敗的,最后你只能得到所有人的分數都和黃忠一樣。
猜測應該是先構造了一個1 * 3 的列表,然后重復了5次,最后外邊加了一個框 像二維數組一樣【實際上並不是】

從下邊的這張圖中就可以明顯地看出來原因!證明我們的推測!

正確代碼

scores = [[None] * len(courses) for _ in range(len(names))]

自我分析

一看外邊的框就知道這是一個列表嵌套,外邊是一個數組,里邊是一個數組。
這樣采用for循環去重復 就解除了列表之間的聯系,每個都不一樣,所以可以單獨編輯不受影響。

總結反思

http://pythontutor.com/visualize.html#mode=display
上述這個鏈接可以看到代碼執行時內存空間及值的分配情況,直觀看出來錯誤原因出現在哪里!
使用列表嵌套時可以先寫個簡單的小例子測試一下
【當然還是知道原理最重要】

參考鏈接

http://c.biancheng.net/view/5659.html


免責聲明!

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



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