![](/img/trans.png)
[英]How to reverse a list without using reverse() and without using return
[英]Recursion reverse list without return value
當我編寫遞歸 function 以就地反轉列表時,我遇到了以下問題。 我可以更改輸入參數。
def reverse_string(s):
if len(s) <= 1:
return
else:
s[0], s[-1] = s[-1], s[0]
reverse_string(s[1:-1])
s = ['A','B','C','D','E','F']
reverse_string(s)
print(s)
output 是
['F', 'B', 'C', 'D', 'E', 'A']
看起來我在遞歸中所做的更改在遞歸調用返回后被回滾。 我不明白為什么。 有人可以幫忙嗎?
切片列表會創建一個新列表,因此修改切片列表對原始列表沒有影響。 相反,您可以使 function 接受一個偏移量作為第二個參數,以便在原始列表上根據列表兩端的偏移量交換項目:
def reverse_string(s, offset=0):
if len(s) > offset * 2:
s[offset], s[-offset - 1] = s[-offset - 1], s[offset]
reverse_string(s, offset + 1)
以便:
s = ['A', 'B', 'C', 'D', 'E', 'F']
reverse_string(s)
print(s)
輸出:
['F', 'E', 'D', 'C', 'B', 'A']
要了解您當前的代碼是如何不工作的,這里有一個使用相同算法的版本。 它只是添加了一些額外的步驟,以便您在每次調用時適當地處理從主列表中切出的列表:
def reverse_string(s):
if len(s) <= 1:
return
else:
s[0], s[-1] = s[-1], s[0]
slice = s[1:-1] # slicing a list creates a new, independent list object
reverse_string(slice) # this call modifies the new list in place, leaving s unchanged
s[1:-1] = slice # so we have to assign the modified slice back to s ourselves
請注意,雖然這確實有效,但效率非常低,因為切片和切片分配都需要在每次遞歸調用時復制列表的大部分。 其他答案提供了更有效的解決方案,涉及始終修改相同的列表,僅使用特定索引而不是始終交換s[0]
和s[-1]
。
還值得注意的是,雖然這是對list
對象進行切片時的行為方式,但 Python 中的其他對象的行為方式可能有所不同。 numpy
數組的切片是另一個數組,但 arrays 是底層數據的淺“視圖”。 就地修改數組的切片通常也會修改數組中的數據。 這可能是好是壞,取決於您是否期望它!
希望這只是一個遞歸練習,這是一個相當低效的python內置通過使用負增量反轉列表的實現
s = ['A','B','C','D','E','F']
print(s[::-1])
對於您的遞歸,請參閱 blhsing 的答案。
由於s[::-1]
是反轉的建議答案,我們也需要解釋reverse
,因為它是反轉切片的最快方法(就地)
s = ['A','B','C','D','E','F']
s.reverse()
print(s)
# ['F', 'E', 'D', 'C', 'B', 'A']
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.