1

我有一个函数,它的名字是 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 

你能帮我找出我的错误以及如何获得正确的递归函数吗?

谢谢你

4

3 回答 3

2

你的第一个问题是这样的:

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.0或添加list_changes[0]到它们,然后调用不影响它们的函数,然后返回它们。所以,你最终会返回0.0, list_changes[0]or 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 无论如何都不做尾递归优化。我认为这是最接近您想要完成的解决方案。

于 2013-04-03T23:56:27.707 回答
2

使用一些累加器(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 个项目,则上述功能将失败。

于 2013-04-03T23:57:21.773 回答
2

不使用尾递归:

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 中,一个人会使用生成器,或者尾递归……如果你想复习递归,只需阅读小计划者

于 2013-04-04T00:05:32.240 回答