yandex
loader

please wait

  • Imran Malik Feb-12-2019 05:43:34 AM ( 3 months ago )
    0
     

    could someone help me understand what the s[1] and s[0] are referring to in the code below? This code will generate a Fibonacci serie. And I am still trying to understand how accumulate() works. Does it return the first value (0,1) as it is, then uses the result from the first application of the lambda function as s[1] and another tuple (0,1) from the list generated by repeat() as s[0]? or s[0] and s[1] are assigned as 0 and 1 respectively?

    Thanks!

    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))
  • Karlie Kloss Feb-12-2019 05:46:58 AM ( 3 months ago )

    indexable[n] is the way to get the value in index n of indexable. Since tuples are indexable collections (they define __getitem__), you're getting the zero-index and one-index of that tuple (the first and second values, respectively).

    This might be better-understood in the no-longer-valid syntax:

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

    As you correctly intuited, accumulate([x1, x2, x3], fn) returns the infinite series [x1, fn(x1, x2), fn(x2, fn(x1, x2)), ...] fn in this case is a function that has the signature:

    def fn(last_last_value, last_value)

     

    The docs probably show this most clearly, using operator.add (aka +)

    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
  • Deepak Parmar Feb-12-2019 05:48:11 AM ( 3 months ago )

    Since p=1 and q=1 and r=0, we can ignore them all together and it ultimately boils down to just this:

    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)
    ...

    as you can see current is never being used

Please login

Similar Discussion

Recommended For You