在每次迭代中使用列表中的两个连续值

时间:2011-08-18 13:28:15

标签: python

我已在下面发布了部分代码。 Newton()函数调用Bezier()函数。 Bezier()函数有一个列表,从中我得到p0和p3。我想要做的是,在第一次迭代中,程序应该将plist中的第一项和第二项作为p0和p3。然后在第二次迭代中,p0和p3是第二和第三项,依此类推。每次迭代时,p0和p3值都应该改变。这就像新的p0是旧的p3。我无法正确地将其放入代码中。谢谢。

import math

w = 1.0

def Newton(poly):
    """ Returns a root of the polynomial"""
    x = 0.5  # initial guess value
    counter = 0
    epsilon = 0.000000000001
    poly_diff = poly_differentiate(poly)

    while True:
        x_n = x - (float(poly_substitute(poly, x)) / float(poly_substitute(poly_diff, x)))
        counter += 1
        if abs(x_n - x) < epsilon :
            break
        x = x_n
        print "\tIteration " , counter , " : ", x_n

    print "u: ", x_n
    Bezier(x_n)

def Bezier(x_n) :
    """ Calculating sampling points using rational bezier curve equation"""
    u = x_n
    plist = [0.5, 0.1, 0.4, 0.35, 0.8, 0.6, 1.0, 0.2, 0.7, 0.9] # list of parameter values of the phonemes

    for i in range(len(plist) - 1) :
        p0 = plist[i]
        p3 = plist[i + 1] 
        p1 = p0
        p2 = p3
        print p0, p3   
        p_u = math.pow(1 - u, 3) * p0 + 3 * u * math.pow(1 - u, 2) * p1 \
            + 3 * (1 - u) * math.pow(u, 2) * p2 + math.pow(u, 3) * p3
        p_u = p_u * w
        d = math.pow(1 - u, 3) * w + 3 * u * w * math.pow(1 - u, 2) + 3 * (1 - u) * w * math.pow(u, 2) + math.pow(u, 3) * w
        p_u = p_u / d

    print "p(u): ", p_u
    return plist

if __name__ == "__main__" :

5 个答案:

答案 0 :(得分:8)

>>> p = [1, 2, 3, 4, 5]
>>> for p1, p2 in zip(p, p[1:]):
...     print p1, p2
... 
1 2
2 3
3 4
4 5

有帮助吗?

答案 1 :(得分:4)

也许来自itertools recipespairwise迭代器会有帮助吗?

from itertools import izip, tee
def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return izip(a, b)

答案 2 :(得分:3)

您实际要求的算法称为滑动窗口,它在一段时间之前出现在itertools食谱中:

from itertools import islice

def window(seq, n=2):
    "Returns a sliding window (of width n) over data from the iterable"
    "   s -> (s0,s1,...s[n-1]), (s1,s2,...,sn), ...                   "
    it = iter(seq)
    result = tuple(islice(it, n))
    if len(result) == n:
        yield result    
    for elem in it:
        result = result[1:] + (elem,)
        yield result

答案 3 :(得分:2)

Bezier功能的顶部更改为

def Bezier(x_n, p0, p3) :
    """ Calculating sampling points using rational bezier curve equation"""
    u = x_n
    p1 = p0
    p2 = p3

彻底摆脱那个循环和plist

然后,在time函数中(根据我对上一个问题getting a boundary of an item from another list的回答),将其更改为:

def time() :
    tlist = [0.0, 0.12, 0.16, 0.2, 0.31, 0.34, 0.38, 0.46, 0.51] # list of start time for the phonemes
    plist = [0.5, 0.1, 0.4, 0.35, 0.8, 0.6, 1.0, 0.2, 0.7, 0.9] # list of parameter values of the phonemes

    total_frames = math.floor(tlist[-1] / 0.04)
    t_u = 0.0
    i = 0
    while i < len(tlist) - 1:
        # if the number is in the range
        # do the calculations and move to the next number
        if t_u > tlist[i] and t_u < tlist[i + 1] :
            print "\n The t_u value:", t_u, 'is between',
            print "start:", tlist[i], " and end: ", tlist[i+1]
            poly = poly_coeff(tlist[i], tlist[i + 1], t_u)
            Newton(poly, plist[i], plist[i+1])
            t_u = t_u + 0.04 # regular time interval

        # if the number is at the lower boundary of the range no need of calculation as u = 0
        elif t_u == tlist[i] :
            print "\n The t_u value:", t_u, 'is on the boundary of',
            print "start:", tlist[i], " and end: ", tlist[i+1]
            print "u : 0"
            Bezier(0, plist[i], plist[i+1])
            t_u = t_u + 0.04 # regular time interval

        # if the number is at the upper boundary of the range no need of calculation as u = 1
        elif t_u == tlist[i + 1] :
            print "\n The t_u value:", t_u, 'is on the boundary of',
            print "start:", tlist[i], " and end: ", tlist[i+1]
            print " u : 1"
            Bezier(1, plist[i], plist[i+1])
            t_u = t_u + 0.04 # regular time interval

        # if the number isn't in the range, move to the next range
        else :
            i += 1

唯一的变化是将plist放在那里并将plist值传递给NewtonBezier

Newton功能的唯一变化是将第一行更改为

def Newton(poly, p0, p3):

的最后一行
    Bezier(x_n, p0, p3)

答案 4 :(得分:1)

生成器可能是我选择的方式,它们简单,容易,并且可以比嵌入式for循环更好地包装和模块化

>>> def solution_pairs(list):
...     for p0, p3 in zip(list, list[1:]):
...         yield (p0, p3)

然后可以在for循环

中明确地使用它
>>> list = [1, 2, 3, 4, 5]
>>> for p0, p3 in solution_pairs(list):
...     print p0, p3
1 2
2 3
3 4
4 5

你甚至可以把你当前拥有的整个for循环包装到一个生成器中,并且如果你愿意的话,让它产生p_u。