簡體   English   中英

沒有返回值的遞歸反向列表

[英]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.

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