有人能向我解釋爲什麼這個函數返回不同的結果:爲什麼這個函數返回不同的結果?
def g(x, z):
x.append(z)
return x
y = [1, 2, 3]
g(y, 4).extend(g(y[:], 4))
y = [1, 2, 3]
g(y[:], 4).extend(g(y, 4))
第一返回
[1, 2, 3, 4, 1, 2, 3, 4, 4]
和第二
[1, 2, 3, 4]
有人能向我解釋爲什麼這個函數返回不同的結果:爲什麼這個函數返回不同的結果?
def g(x, z):
x.append(z)
return x
y = [1, 2, 3]
g(y, 4).extend(g(y[:], 4))
y = [1, 2, 3]
g(y[:], 4).extend(g(y, 4))
第一返回
[1, 2, 3, 4, 1, 2, 3, 4, 4]
和第二
[1, 2, 3, 4]
在你路過列表中的第一個電話參考,在第二次電話會議上,您製作了一份清單副本(將其列入清單)。 解釋:
>>> one = [1,2,3]
>>> ref = one
>>> copy = one[:]
>>> one
[3, 2, 3]
>>> ref
[3, 2, 3]
>>> copy
[1, 2, 3]
你對作業和副本做了一個混亂。需要注意的是:
append()
修改就地列表中,而無需創建一個新的extend()
y[:]
並創建一個新的列表你的表情回到None
。您只對列表進行修改,不保存對新列表的引用。
讓我「展開」你的代碼,以示區別:
# First snippet:
y = [1, 2, 3]
y.append(4)
y_copy = list(y)
y_copy.append(4)
y.extend(y_copy)
# Second snippet:
y = [1, 2, 3]
y_copy = list(y)
y_copy.append(4)
y.append(4)
y_copy.extend(y)
正如你所看到的,在第二個例子中,你最適用修改到副本,而不是原來的。首先,所有更改都轉到原始。
從主觀上看,該代碼片段很難理解。你自己寫的,不能遵循它,而且我有多年的Python經驗,並且仍然需要拉開「展開」的訣竅。儘量保持代碼簡單,以便可以跟蹤和推理對象。
在這兩種情況下,返回None
,因爲list.extend()
擴展名單就地。所以你一定要看看y
的結局如何。這就是摩擦的地方;在第二個例子中,你沒有擴展y
本身。
在第一個例子,你基本上是這樣做:
y.append(4) # y = [1, 2, 3, 4]
temp_copy = y[:] # temp_copy = [1, 2, 3, 4]
temp_copy.append(4) # temp_copy = [1, 2, 3, 4, 4]
y.extend(temp_copy) # y = [1, 2, 3, 4, 1, 2, 3, 4, 4]
del temp_copy
print(y)
的temp_copy
名字從來沒有真正建立;該列表僅在堆棧中可用,並且在g()
之內簡寫爲x
,這就是爲什麼我在末尾再次刪除temp_copy
以便清楚說明。
所以y
首先附加到,然後擴展與另一個列表(這恰好是與另一個元素添加y
副本)。
在你的第二個例子,你這樣做,而不是:
temp_copy = y[:] # temp_copy = [1, 2, 3]
temp_copy.append(4) # temp_copy = [1, 2, 3, 4]
y.append(4) # y = [1, 2, 3, 4]
temp_copy.extend(y) # temp_copy = [1, 2, 3, 4, 1, 2, 3, 4]
del temp_copy
print(y)
你追加一個元素y
,和所有其他的操作應用到副本。副本是再次丟棄,因爲在你的代碼中沒有對它的引用。
啊我現在明白了,謝謝你的詳細回覆 – nihilistexistance
實際上都返回'None'。你的意思是'y'被設置爲那個值? –
爲什麼你要這麼長時間才能使Python列表操作變得如此複雜? –