ссылка на элемент внутри метода накапливания - PullRequest
0 голосов
/ 12 февраля 2019

Может ли кто-нибудь помочь мне понять, на что ссылаются s [1] и s [0] в приведенном ниже коде?Этот код будет генерировать серию Фибоначчи.И я все еще пытаюсь понять, как работает накопление ().Возвращает ли оно первое значение (0,1) как есть, затем использует результат первого применения лямбда-функции как s [1] и другой кортеж (0,1) из списка, сгенерированного repeat (), как 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 голосов
/ 12 февраля 2019

Поскольку p=1 и q=1 и r=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 никогда не привыкает.В вашем коде i равен current, s равен prev, и поэтому s[0] == prev[0] является первым элементом в кортеже, а s[1] является вторым элементом

0 голосов
/ 12 февраля 2019

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)

Документы , вероятно, показывают это наиболее четко, используя 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
...