一些复杂的列表计算和切片;如何使它工作?

时间:2014-02-12 19:47:52

标签: python list python-2.7

我最近一直在研究一个问题。这个任务似乎很容易解释,但对我来说代码很复杂。我尝试了很多变化,但所有变化都缺失了。不知道是什么。需要有人在外面发表意见,因为我的思维方式太深,有时无法注意到简单的东西

我会尝试在此处简化问题,以便更容易理解。

所以我们有一个包含对象的列表

lst = [A0, A1, A2, A3, A4]

我需要做的是,运行一个名为predict()的方法,并从lst中的每个元素中获取预测元素Ap。此方法必须运行3次,因此对于A0,我将获得Ap1Ap2Ap3。但是,predict()执行的计算依赖于列表的前一个元素以及它提供的结果。因此,Ap1仅从A0计算,但Ap2是根据A0Ap1计算的(它们作为输入传递给predict(),并且Ap3是根据A0, Ap1, Ap2计算的。所有这些计算都是A0完成的。随着lst中每个后续元素的考虑,计算变得更加复杂。初始投入增长。

下面的“流程图”可能会有所帮助。

=============================================== =========

1)案例A0

A0 ---> predict([A0]) ---> Ap1

A0, Ap1 ---> predict([A0,Ap1]) ---> Ap2

A0, Ap1, Ap2 ---> predict([A0,Ap1,Ap2]) ---> Ap3

=============================================== ==========

2)case A1 - 考虑初始输入的前一个元素

A0, A1 ---> predict([A0,A1]) ---> Ap2

A0, A1, Ap2 ---> predict([A0,A1,Ap2]) ---> Ap3

*|A0|* A1, Ap2, Ap3 ---> predict([Ap1,Ap2,Ap3]) ---> Ap4 [缩短了输入内容]

这里是棘手的部分,因为你可以注意到当输入有3个以上的元素时,输入数据会在右边的一个位置移动。 我决定采用这种“滑动窗口”方法,因为否则用于计算A17的输入将包括所有AX,其中X< 17.因此,最多只有3个元素作为初始输入就足够了

=============================================== =============

为了进一步说明,我还将提供A2的案例。

3)案例A2

A0, A1, A2 ---> predict([A0,A1,A2]) ---> Ap3

*|A0|*, A1, A2, Ap3, ---> predict([A1,Ap2,Ap3]) ---> Ap4 [缩短了输入内容]

*|A0|* *|A1|*, Ap2, Ap3, Ap4 ---> predict([Ap2,Ap3,Ap4]) ---> Ap5 [缩短了输入内容]

=============================================== ==============

正如您所看到的,当初始输入长于3时,存在一般模式,并且必须使用一些“滑动窗口”方法。并且在初始输入小于3

时存在特定情况

为简化所有这些内容,我使用了以下代码:

current_trace = [[2,4,6,7,6,3],[1,2,5,7,2,7],[6,4,7,1,8,2]]


def predict(lst):
    print "predicting for", lst
    print "result", max(lst) + 0.0
    return max(lst) + 0.0

接近1:

for user_trace in current_trace:
    y = 1
    for counter in range(len(user_trace)):
        while y <= 3:
            x = 0
            intermediate_list = user_trace[x:y]
            while len(intermediate_list) <= 5:              
                next_prediction = predict(intermediate_list)  
                intermediate_list.append(next_prediction)
            #predict(user_trace[x:y])
            #print "@while" ,user_trace[x:y]
            print "end of prediction \n"
            y += 1

        else:
            print "\n"
            x = y - 3
            if len(user_trace[x:y]) == 3:
                predict(user_trace[x:y])
                #print "@else" ,user_trace[x:y]
            else:
                pass
            y += 1 

方法2:

for user_trace in current_trace:
    for slicer in range(len(user_trace)):
        new_list = user_trace[:slicer+1]
        if len(new_list) <= 3:
            print "slicer:", slicer
            print new_list
        else:
            print "slicer:", slicer
            newer_list = new_list[-3:]
            print newer_list 

在这两种情况下,我都错过了一些东西,希望有人可以给我一个评论,或者有用的建议,因为我现在已经把这件事用了几天,这让我感到很沮丧!

提前致谢,

最佳, w ^

2 个答案:

答案 0 :(得分:3)

我认为你想要的是一个移动窗口,长度(最多)3在列表中。您可以按如下方式执行此操作:

def windows(l, n=3):
    for x in range(1, len(l)+n): # or len(l)+1 to stop at last full window
        yield(l[max(0, x-n):x])

例如:

>>> list(windows([1,2,3,4,5]))
[[1], [1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5], [5]]

答案 1 :(得分:0)

从@jonrsharpe建议的想法开始,我以这种形式写了一个解决方案

def predict(lst):
    print "predicting for", lst
    print "result", max(lst) + 0.0
    return max(lst) + 0.0

def window(lst, n=3):
    for x in range(1, len(lst)+1): # or len(l)+n to continue till the end
        yield(lst[max(0, x-n):x])

def sliding_tristep(full_trace, future_step = 2, window_size = 3):

    for user_trace in full_trace:
        for current_input in window(user_trace):
            counter = 0
            trace = current_input
            accumulator = []
            while counter <= future_step:      # this loop is used to define how many times you want to perform the given function (in this case predict())
                next_prediction = predict(trace)  
                trace.append(next_prediction)
                accumulator.append(next_prediction)
                trace = trace[-window_size:]    # slicing the next input happens here
                counter += 1

            print current_input, accumulator