Python創建二維列表的正確姿勢


Python創建二維列表的正確姿勢


簡介

Python中沒有數組,使用list結構代替,並且list結構的功能更加強大:

  • 支持動態擴容,無需擔心元素過量
  • 對list內的元素類型不做一致性約束
  • 提供豐富的方法:pop、insert、sort、index等等
  • ...

list也是我們最常使用的一種結構,我們也需要了解它的一些特性,學會正確使用它。

探索列表的初始化

初始化一維列表

>>> month = ["January", "February", "March"]

初始化二維列表

>>> row, col = 3, 4
>>> right_matrix = [[0] * col for _ in range(row)]
>>> wrong_matrix = [[0] * col] * row
>>> print(right_matrix)
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
>>> print(wrong_matrix)
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

看似兩種方式初始化出的二維列表是一樣的,但為啥第二種是wrong_matrix呢?它會有問題呢?
如果我們嘗試更新試試

>>> right_matrix[0][0] = 1
>>> print(right_matrix)
[[1, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] # 正常
>>> wrong_matrix[0][0] = 1
>>> print(wrong_matrix)
[[1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0]] # 不正常,每行第一列都被更新成了1

分析兩種初始化方式的內存情況

率先想到的是list屬於可變數據結,在函數傳遞過程中容易發生淺拷貝(在函數內部的更改不會影響函數外部該變量的值)。

>>> id(right_matrix[0]), id(right_matrix[1]), id(right_matrix[2])
(288926611776, 288926609600, 288926609472)
>>> id(wrong_matrix[0]), id(wrong_matrix[1]), id(wrong_matrix[2])
(288926610176, 288926610176, 288926610176)

使用id()函數可以獲取對象的內存id,發現right_martix中每行的id是不同的,它們都是獨立的list對象,而wrong_matrix中每行的id是相同的,它們是同一個lsit對象,所以會出現上面的情況:目的是改wrong_matrix[0][0],但實際上wrong_matrix[1][0]wrong_martix[2][0]也被修改了。

使用http://pythontutor.com/visualize.html#mode=edit 網站執行上面的right_matrixwrong_matrix代碼來對比實際的內存情況,來驗證一下

right_matrix:

wrong_matrix:

right_matrix中每個list對象都有獨立的內存空間,而wrong_matrix中每個list對象指向同一塊內存空間。

結論

list的元素如果是可變數據類型,一定要用方法一的方式初始化

>>> row, col = 3, 4
>>> right_matrix = [[0] * col for _ in range(row)]

這種方式下,right_matrix里的每個list對象都有獨立的內存空間,不會出現修right_matrix[0][0]right_matrix[1][0]right_martix[2][0]也被修改的情況。


免責聲明!

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



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