簡體   English   中英

遞歸技術而不是python中的列表技術

[英]recursive technique rather than lists technique in python

我有一個函數,其名稱為positive_negative

def positive_negative(list_changes):
    """ (list of number) -> (number, number) tuple

    list_changes contains a list of float numbers. Return a 2-item
    tuple where the first item is the sum of the positive numbers in list_changes and
    the second is the sum of the negative numbers in list_changes.

    >>> positive_negative([0.01, 0.03, -0.02, -0.14, 0, 0, 0.10, -0.01])
    (0.14, -0.17)
    """

我可以使用列表技術編寫此功能,如下所示:

def positive_negative(list_changes):
    pos = sum([item for item in list_changes if item > 0.0])
    neg = sum ([item for item in list_changes if item < 0.0]) 
    return pos, neg

這是一個很好的解決方案。 現在我的問題是如何使用遞歸技術來解決相同的功能,我已經嘗試了以下代碼,但是不幸的是出了點問題。

def positive_negative(list_changes):
    pos = 0.0
    neg = 0.0
    if len(list_changes)== 0:
        pos =+ 0.0
        neg =+ 0.0
        return pos,neg
    else:
        if list_changes[0] > 0.0 :
            pos =+ list_changes[0]
        else:
            neg =+ list_changes[0]
        positive_negative(list_changes[1:])


    return pos,neg 

您能否幫助我找到我的錯誤以及如何獲取正確的遞歸函數。

謝謝

您的第一個問題是:

pos =+ list_changes[0]

Python沒有=+運算符。 因此,這等效於:

pos = (+list_changes[0])

由於list_changes[0]是一個數字,並且+n對於任何數字都與n相同(在某些無關緊要的情況下(此處無關緊要)除外),因此您只是在每次替換pos而不是添加它。

您可能想要這樣:

pos += list_changes[0]

但是,您完全嘗試使用+=的事實是一個更根本的誤解。 堆棧上的positive_negative每個實例都有其自己的posneg值。 它們從0.0開始,然后向它們添加0.0list_changes[0] ,然后調用不影響它們的函數,然后返回它們。 因此,您最終將返回0.0, list_changes[0]list_changes[0], 0.0 ; 列表中以后出現的任何內容都不會影響結果。


如果您希望遞歸函數調用添加任何內容,則需要對其返回值進行處理。 像這樣:

def positive_negative(list_changes):
    if len(list_changes)== 0:
        return 0.0, 0.0
    else:
        pos, neg = positive_negative(list_changes[1:])
        if list_changes[0] > 0.0:
            pos += list_changes[0]
        else:
            neg += list_changes[0]
        return pos, neg

當然,該解決方案顯然不是尾遞歸……但這沒關系,因為Python仍然不進行尾遞歸優化。 我認為這是您要完成的工作中最接近的解決方案。

使用一些累加器(psum,nsum):

def positive_negative(list_changes, psum=0, nsum=0):
    if len(list_changes) == 0:
            return psum, nsum
    if list_changes[0] < 0:
            nsum += list_changes[0]
    else:
            psum += list_changes[0]
    return positive_negative(list_changes[1:], psum, nsum)

# and another version:
def positive_negative2(list_changes, psum=0, nsum=0):
    if len(list_changes) == 0:
            return psum, nsum
    if list_changes[0] < 0:
            return positive_negative(list_changes[1:], 
                            psum, nsum + list_changes[0])
    return positive_negative(list_changes[1:], 
                            psum + list_changes[0], nsum)

print positive_negative([0.01, 0.03, -0.02, -0.14, 0, 0, 0.10, -0.01])

輸出量

(0.14, -0.17)

附帶說明一下,python不會進行尾部調用優化,因此在使用遞歸時要謹慎。 如果您的列表中包含大約1000個項目,則上述功能將失敗。

不使用尾遞歸:

import operator


def positive_negative_change(l):
    if not l:
        return (0.0, 0.0)

    if l[0] >= 0:
        return tuple(map(operator.add, (l[0], 0.0),
                         positive_negative_change(l[1:])))
    else:
        return tuple(map(operator.add, (0.0, l[0]),
                         positive_negative_change(l[1:])))

在python中,將使用生成器,或尾部遞歸...如果您要整理遞歸,請閱讀小備案

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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