递归函数,它接受一个列表并返回一个排序列表

时间:2016-11-01 02:47:33

标签: python recursion

我正在处理sort函数,它是一个递归函数,它接受一个列表并返回一个已排序的列表。(使用递归是一种要求)。

def separate(p : callable, l : [object]) -> ([object],[object]):
    if l == []:
        return([],[])
    else:
        if p(l[0]):
            return (separate(p, l[1:])[0]+[l[0]],separate(p, l[1:])[1])
        else:
            return (separate(p, l[1:])[0], separate(p, l[1:])[1]+[l[0]])

def sort(l : [object]) -> [object]:

    z = separate((lambda x: [y > x[0] for y in x]),l)
    return sort(z[0]) + sort(z[1])

单独的函数传递谓词和列表;它返回一个2元组,其0索引是谓词返回True的参数列表中所有值的列表,其1索引是谓词返回False的参数列表中所有值的列表。例如:

separate((lambda x:x>=0),[1,-3,-2,4,0,-1,8])

返回

([1,4,0,8],[-3,-2,-1])

sort函数调用单独的函数将列表分成两个列表。 sort中的lambda函数用于比较列表中的元素是否大于列表中的第一个元素。然后,在这两个列表中的每一个上递归调用sort并返回包含第一个列表中排序值的单个列表(较小的列表),然后是用于分隔列表的值,后跟第二个列表中的排序值(较大的)

sort([4,5,3,1,2,7,6])首先分别调用,计算列表[3,1,2]和[5,7,6](注意4,用于进行分离的列表中的第一个值不在任何一个列表中,当排序时将是[1,2,3]和[5,6,7],导致返回列表

[1,2,3,4,5,6,7] 

(将4放在结果列表中,在正确的位置)。

我已经测试了我的单独功能,它运行正常。

现在,我尝试编写函数sort,它显示'int'对象不可迭代,我添加了下面的错误:

29 # Test sort
30 *Error: sort([1,2,3,4,5,6,7]) raised exception TypeError: 'int' object is not iterable
31 *Error: sort([7,6,5,4,3,2,1]) raised exception TypeError: 'int' object is not iterable
32 *Error: sort([4,5,3,1,2,7,6]) raised exception TypeError: 'int' object is not iterable
33 *Error: sort([1,7,2,6,3,5,4]) raised exception TypeError: 'int' object is not iterable
36 *Error: l = sort(l) raised exception TypeError: 'int' object is not iterable
37 *Error: l -> [8, 5, 9, 4, 29, 28, 11, 19, 7, 15, 25, 6, 12, 10, 22, 17, 21, 3, 27, 23, 1, 20, 13, 2, 30, 16, 26, 24, 18, 14] but should -> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]

我不知道为什么会出现此错误,有人可以帮我修复排序功能吗?非常感谢。

1 个答案:

答案 0 :(得分:1)

首先,你的separate()功能一团糟。您重新计算separate(p, l[1:]),只是将其编入索引两次,而不是使用局部变量:

return (separate(p, l[1:])[0] + [l[0]], separate(p, l[1:])[1])

您的sort()例程需要一个基本案例;你无法获得空列表的第一个元素;你抓住错误列表的第一个元素;你通过让它处理整个列表而不是一个元素来违反你自己的谓词函数设计的逻辑!

这里是您的代码的返工,试图解决上述问题并稍微清理一下风格:

def separate(predicate: callable, array: [object]) -> ([object], [object]):

    if not array:
        return list(), list()

    positive, negative = separate(predicate, array[1:])

    if predicate(array[0]):

        return [array[0]] + positive, negative

    return positive, [array[0]] + negative


def sort(array: [object]) -> [object]:

    if not array:
        return array  # avoid next statement if array is empty

    first = array[0]

    lesser, greater = separate(lambda x: x < first, array[1:])

    return sort(lesser) + [first] + sort(greater)


print(sort([4, 5, 3, 1, 2, 7, 6]))

根据需要,它返回:

[1, 2, 3, 4, 5, 6, 7]