Python 用 * (重複運算符) 和迭代器生成 list 有何不同?

使用 [[0] * n] * m 和 [[0] * n for i in range(m)] 生成list時會使程序產生不同的結果。難道不都是二維數組嗎?

代碼如下:

可以發現我只是改變了 dp 和 dp1 的名字,但卻得到了不同的結果,而且dp == dp1 返回 True,這讓我完全無法理解。


自然是不一樣的,Python中的list是個對象,對象保存引用,[[0] * n] * m是一個長度為m的列表,其中的每個元素都是同一個list的引用,而[[0] * n for i in range(m)]是一個長度為m的列表,其中的每個元素是各自不相同的list對象


題干中的代碼太難認,就不看了,按照題干文字描述,粗略介紹下 [[0] * n] * m[[0] * n for i in range(m)] 有什麼不同:

驗證如下:

In [1]: m, n = 5, 4

In [2]: lst1 = [[0] * n] * m

In [3]: lst1[0] is lst1[1]
Out[3]: True

In [4]: lst1[0] == lst1[1]
Out[4]: True

In [5]: lst2 = [[0] * n for i in range(m)]

In [6]: lst2[0] is lst2[1]
Out[6]: False

In [7]: lst2[0] == lst2[1]
Out[7]: True


為什麼你們都會被這麼明顯的細節坑了呢?

舊比喻不太準確:你爸媽生了你和其他九個你的兄弟姐妹和有人拿你的細胞克隆了九份這能一樣么?(雖然都是十個長得像的人)

來個新的:你有9個克隆體,和你有10個名字,這是一回事么?


樓上兩位大神已經說明得很清楚了


[[]] * 10:

tmp = []

l = []

for i in range(10): l.append(tmp)

[[] for i in range(10)]:

l = []

for i in range(10): tmp = []; l.append(tmp)


第一種是常見的坑新手的做法,好些個不明白傳值傳引用的兄弟在這都跪了。第二種是正確的做法。


對list使用*生成的是淺拷貝。


推薦閱讀:

學習python有什麼用?python的實際應用有哪些?
Python為什麼用不了?
沒有自學過任何計算機語言的人如何在大學中達到或超越那些」有底子」的大神?
編程零基礎如何著手學習python?
如何畫出一段複雜代碼中函數的棧圖?

TAG:Python | Python入門 |