在python中查找所有最大单调子序列

时间:2014-07-15 13:16:55

标签: python list

现在试图弄清楚如何按顺序找到所有最大子序列(正面和负面)。在这里我遇到了一些麻烦,因为找不到合适的解决方案。我有这个代码,但输出只适用于正数。我是python的新手,所以无法在短时间内弄清楚如何处理它。

testcase = [1,2,3,4,5,4,3,2,1,0,-1,-2,-3,-2,-1,-2,-1,-2,-3,-4,-5]
def process(lst):
    def sub(lst):
        temp = []
        while lst and (not temp or temp[-1] <= lst[0]):
            temp.append(lst[0])
            lst = lst[1:]
        return temp, lst

    res=[]
    while lst:
        subres, lst = sub(lst)
        res.append(subres[0] if len(subres)==1 else subres) 
    return res
if __name__ == "__main__":
    print(process(testcase))

因此,样本输出是

[[1, 2, 3, 4, 5], 4, 3, 2, 1, 0, -1, -2, [-3, -2, -1], [-2, -1], -2, -3, -4, -5]]

虽然,我希望它是

[[1,2,3,4],[5,4,3,2,1,0,-1,-2,-3],[-2,-1],-2,[-1,-2,-3,-4,-5]]

所以,问题是如何做到这一点?

1 个答案:

答案 0 :(得分:2)

您基本上需要跟踪“派生”(元素之间的差异),并查看它何时改变方向。

您可以使用numpy

非常干净地表达这一点
import numpy as np
np_split_indexes= np.where(np.diff(np.diff(testcase))!=0)[0]+2
split_indexes= [0] + list(np_split_indexes) + [len(testcase)]
result= [testcase[a:b] for a,b in zip(split_indexes[:-1],split_indexes[1:])]

或者,如果您更喜欢纯python:

result=[]
tmp=[]
last_direction=0;
last_element=0;
for x in testcase:
    direction= (x-last_element)/abs(x-last_element) #math trick - divide by the magnitude to get the direction (-1/1)
    last_element= x
    if (direction!=last_direction) and tmp:
        result.append(tmp)
        tmp=[]
    last_direction= direction
    tmp.append(x)
if tmp:
    result.append(tmp)

print result

输出:

[[1, 2, 3, 4, 5], [4, 3, 2, 1, 0, -1, -2, -3], [-2, -1], [-2], [-1], [-2, -3, -4, -5]]

请注意,这与您最终的预期输出不同。我不确定为什么你将-1归为最后一组,因为它是本地最大值。