我的教授發佈了下面的函數。我不完全瞭解它是如何工作的。有人可以解釋嗎?Python:反轉函數的解釋
def rev(a):
if a == []:
return []
else:
return rev(a[1:]) + [a[0]]
我的教授發佈了下面的函數。我不完全瞭解它是如何工作的。有人可以解釋嗎?Python:反轉函數的解釋
def rev(a):
if a == []:
return []
else:
return rev(a[1:]) + [a[0]]
這是做什麼遞歸反轉列表。查看它是如何工作的最簡單的方法是follow through the execution。
該函數接受字符串,並通過返回第一項(第一項)的反轉版本(a[1:]
)並將第一項附加到結尾來解決該問題。
請注意,在真實情況下(我假設您的教授只是顯示遞歸的想法),這是一種糟糕的方式,因爲Python沒有針對遞歸進行優化。相反,請使用the reversed()
builtin。
另外,它不是特別的Pythonic代碼。如果一個有有一個遞歸解決方案,而不是通過高效率的,有效的,經過嚴格測試的,易於使用的內置,可考慮:
def rev(seq):
return rev(seq[1:]) + [seq[0]] if seq else []
if/else
。a
與seq
使得功能更加清晰 - Python沒有嚴格的數據類型,所以使用提供線索給函數取什麼名字(在這種情況下,序列),使得它更清晰。seq
來取代a == []
。由於列表在空值時評估爲False
,因此不需要與空列表進行比較。a是一個列表。如果a是空列表,則返回空列表。如果沒有,你(遞歸)應用你的'反向'函數到列表中,但是第一個元素,並且你追加了第一個元素。這樣,在每次遞歸調用時,都會從最右邊的元素開始構建反轉列表。
這是一個例子:
l=[1,4,6,7]
rev(l) returns rev([4,6,7])+[1]
rev([4,6,7]) returns rev([6,7])+[4]
...
和到底你有轉([])返回空列表和終止所述遞歸調用。
BTW,扭轉名單l
,只需使用
l[::-1]
謝謝。這就說得通了! –
雖然用「-1」的步驟切片是一個很好的技巧,但它通常是一個壞主意,因爲它依賴於執行該操作的對象。使用內置的「reversed()」通常是一個更好的主意,它可以讓實現進行特殊情況的逆向優化,並且更具可讀性。 –
另外,你每一次,它涉及到的副本列表進行切片。但我猜這只是一個說明性的標準函數式編程(Scala/Erlang)習語的Python實現。 –
對不起,我應該澄清。我知道它做了什麼,只是不知道它是如何做到的。 –
@Adam_G按照我的鏈接開始並逐步執行,它應該使它非常清晰。該網站並沒有笨拙地試圖解釋這裏的步驟,而是將執行情況可視化。 –