累加方法中的元素引用

时间:2019-02-12 05:03:45

标签: python python-3.x itertools

有人可以帮助我理解下面的代码中s [1]和s [0]指的是什么吗?此代码将生成斐波那契系列。而且我仍在尝试了解accumulate()的工作方式。它是否按原样返回第一个值(0,1),然后将lambda函数的第一个应用程序的结果用作s [1],并使用repeat()生成的列表中的另一个元组(0,1)作为s [0]?或s [0]和s [1]分别指定为0和1?

谢谢!

import itertools as it
def second_order(p, q, r, initial_values):
    """Return sequence defined by s(n) = p * s(n-1) + q * s(n-2) + r."""
    intermediate = it.accumulate(
        it.repeat(initial_values),
        lambda s, i: (s[1], p*s[1] + q*s[0] + r)
    )
    return intermediate
fibs = second_order(p=1, q=1, r=0, initial_values=(0, 1))
list(next(fibs) for n in range(8))

2 个答案:

答案 0 :(得分:0)

indexable[n]是获取n的索引indexable中的值的方法。由于元组是可索引的集合(它们定义了__getitem__),因此您将获得该元组的零索引和单索引(分别是第一个值和第二个值)。

使用不再有效的语法可能会更好地理解这一点:

lambda (s1, s2), i: (s2, p*s2 + q*s1 + r)

正确理解后,accumulate([x1, x2, x3], fn)返回无穷级数[x1, fn(x1, x2), fn(x2, fn(x1, x2)), ...] fn,在这种情况下,该函数具有签名:

def fn(last_last_value, last_value)

The docs可能使用operator.add(又名+)最清楚地显示了这一点

def accumulate(iterable, func=operator.add):
    'Return running totals'
    # accumulate([1,2,3,4,5]) --> 1 3 6 10 15
    # accumulate([1,2,3,4,5], operator.mul) --> 1 2 6 24 120
    it = iter(iterable)
    try:
        total = next(it)
    except StopIteration:
        return
    yield total
    for element in it:
        total = func(total, element)
        yield total

答案 1 :(得分:0)

由于p=1q=1r=0,我们可以完全忽略它们,最终归结为:

it.accumulate( 
    [(0,1),(0,1),(0,1),(0,1),(0,1), ...], 
    lambda prev, current: (prev[1], prev[1] + prev[0])
)

您可以像这样可视化它:

0th:                             -> result0= (0,1)
1th: prev=(0,1)    current=(0,1) -> result1= (1, 0+1)= (1,1)
2nd: prev=result1  current=(0,1) -> result2= (0+1, 0+1+1)= (1,2)
3rd: prev=result2  current=(0,1) -> result3= (0+1+1, 0+1+1+0+1)= (2,3)
4th: prev=result3  current=(0,1) -> result4= (0+1+1+0+1, 0+1+1+0+1+0+1+1)= (3,5)
...

您可以看到current从未被使用过。
在您的代码中,icurrentsprev,因此s[0] == prev[0]是元组的第一个元素,而s[1]是第二个元素