我是否應該返回通過引用傳遞并修改過的列表?

更新時間:2024-04-02 11:41:33

問題闡述

我最近發現,Python中的列表是通過引用自動傳遞的(除非使用符號✤數組[:])。例如,這兩個函數執行相同的操作:

def foo(z):
    z.append(3)

def bar(z):
    z.append(3)
    return z

x = [1, 2]
y = [1, 2]
foo(x)
bar(y)
print(x, y)

在此之前,我總是返回我操作過的數組,因為我認為我必須這樣做。現在,我知道這是多余的(可能效率很低),但返回值似乎通常是代碼可讀性的良好實踐。我的問題是,做這兩種方法中的任何一種都有什么問題嗎/最佳實踐是什么?🌠有沒有我錯過的第三個選擇?如果以前有人問過這個問題,我很抱歉,但我找不到任何真正回答我問題的東西。

精準答案

此答案的前提是已經決定是就地修改您的輸入還是返回副本。

正如您所提到的,是否返回修改后的對象是見仁見智的,因為結果在功能上是等價的。通常,NOT返回就地修改的列表被認為是一種好的形式。根據Zen of Python(第二項):

顯式優于隱式。

這一點在標準庫中得到了證實。List方法因此而臭名昭著:list.append, insert, extendlist.sort等。

Numpy也經常使用這種模式,因為它經常處理復制和返回不切實際的大型數據集。一個常見的例子是數組方法numpy.ndarray.sort,不要與返回新副本的頂級函數numpy.sort混淆。

這個想法在很大程度上是Python思維方式的一部分。以下是Guido's email的摘錄,解釋了原因:

我發現鏈接對可讀性構成了威脅;它要求讀者必須非常熟悉每種方法。第二個[未鏈接]形式清楚地表明,這些調用中的每個都作用于同一個對象,因此即使您不太了解類及其方法,您也可以理解第二個和第三個調用應用于x(并且所有調用都是為了它們的副作用),而不是🌄應用于其他對象。