[英]What's the difference between list[::] and list?
這是一個將矩陣順時針旋轉90度的問題,我不明白為什么我不能使用:
matrix = zip(*matrix[::-1])
但:
class Solution:
def rotate(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: void Do not return anything, modify matrix in-place instead.
"""
matrix[::] = zip(*matrix[::-1])
matrix
中的方法是將基體對象的引用。 分配給matrix
會更改matrix
以引用您新創建的對象,但不會更改原始對象的內容。 matrix[::] =
在matrix
引用的對象上調用__setitem__
,該對象相應地更改了對象的內容。
在Python中,所有分配都將引用綁定到名稱。 操作員調用現有參考文獻1的方法 。 就您而言,聲明
matrix = ...
純粹是一項任務2 。 它計算右側,並將其綁定到局部函數范圍內的名稱matrix
。 傳遞對象時引用的任何對象matrix
保持不變。
這就是為什么您看不到所做更改的原因。 並不是說該功能不能以這種方式工作,而是對旋轉后的列表沒有任何作用。 該函數退出后,數據將立即丟棄。
手術
matrix[:] = ...
另一方面,盡管=
符號3 ,但在語義上不是賦值。 這是對matrix.__setitem__(...)
4的調用。 與其他任何方法一樣, __setitem__
方法可直接在對象上操作,而無需更改其名稱綁定。
就索引而言, [:]
等效於[::]
。 它們分別是[0:len(matrix)]
和[0:len(matrix):1]
簡寫。 在這兩種情況下,都將使用默認步長。 通常,任何包含冒號的索引都將轉換為slice
對象。 缺少的元素設置為“ None
並替換為此處顯示的特定於序列的默認值。
1一些運算符,例如+=
,在調用方法后執行賦值。 這些被稱為擴充作業 。 但這不是我們現在感興趣的情況。
2除了文字賦值語句 ( =
)外,其他一些類型的賦值是def
(將功能對象綁定到其名稱), class
(對類對象執行相同的操作), import
(將模塊或模塊元素綁定)名稱),將參數傳遞給函數(將對象綁定到局部參數名稱或kwarg字典鍵)和for
(將元素從迭代器綁定到循環變量)。
3從解析器的角度來看,這仍然是一個任務 ,但是對語句的處理完全不同。 實際上不是賦值的類似語句是在實現為描述符的屬性(例如property
上使用=
運算符。
4從技術上講,它更等效於type(matrix).__setitem__(matrix, ...)
,但還有一些其他優化。 例如,將永遠不會搜索type(matrix)
的元類。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.