簡體   English   中英

關於在Python函數中就地修改列表的方法

[英]About the way to modify the list in-place in a function in Python

如果我嘗試按以下方式就地修改“木板”列表,則它不起作用,似乎它會生成一些新的“木板”,而不是就地修改。

def func(self, board):
    """
    :type board: List[List[str]]
    """
    board = [['A' for j in range(len(board[0]))] for i in range(len(board))]

    return 

我必須做這樣的事情才能就地進行修改,這是什么原因? 謝謝。

    for i in range(len(board)):
        for j in range(len(board[0])):
            board[i][j] = 'A'

您似乎了解這兩種情況之間的區別,並且想知道為什么Python使您以不同的方式處理它們?

我必須做這樣的事情才能就地進行修改,這是什么原因?


創建新副本是有價值的。 因此,使其成為一種表達是有意義的。 實際上,列表推導如果不是表達式,將毫無用處。

就地改變列表是沒有價值的。 因此,沒有理由使其成為表達式,實際上這樣做很奇怪。 當然,您可以提出某種價值(例如,列表被突變)。 但這與Python設計中的其他所有內容都不一致: spam.append(eggs)不返回spam ,它不返回任何內容。 spam = eggs沒有價值。 等等。


其次,理解風格很好地融入了可迭代的范式,這是Python的基礎。 例如,請注意,只需將[…]更改為(…) ,就可以將列表推導轉換為生成器推導(這使您可以對按需計算的值進行延遲的迭代(…) 突變會有什么有用的等效物?

使轉換副本更方便也鼓勵人們使用非變異樣式,這通常可以為許多問題提供更好的答案。 當您想知道如何避免編寫三行嵌套語句來對某些全局變量進行突變時,答案是停止對該全局變量進行突變,而是傳遞一個參數並返回新值。

此外,語法是從Haskell中,在沒有突變的復制。


但是,所有那些“經常”和“通常”並不意味着“從不”。 有時(除非您設計的語言沒有變異),否則您需要就地執行操作。 這就是為什么我們list.sort以及sorted (並且已經做了很多工作來優化list.sort的地獄;這不僅僅是事后的想法。)

Python不會阻止您這樣做。 它只是不彎腰遠,使之容易,因為它為復制。

那沒有修改它。 列表理解語法[x for y in z]在創建一個新列表。 此語法不會修改原始列表。 使函數內部的名稱指向新列表不會更改函數外部名稱所指向的列表。

換句話說,當調用函數時,python傳遞對對象的引用,而不是對名稱的引用,因此,沒有簡單的方法來更改函數外部的變量名所指向的對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM