0

Am a beginner on Python (self studying) and got introduced to Lambda (nameless) function but I am unable to deduce the below expression for Fibonacci series (got from Google) but no explanation available online (Google) as to how this is evaluated (step by step). Having a lot of brain power here, I thought somebody can help me with that. Can you help evaluate this step by step and explain ?

lambda n: reduce(lambda x, _: x+[x[-1]+x[-2]],range(n-2), [0, 1])

Thanks in advance.

(Thanks xnkr, for the suggestion on a reduce function explained and yes, am able to understand that and it was part of the self training I did but what I do not understand is how this works for lambda x, _ : x+[x[-1]+x[-2]],range(n-2), [0, 1]. It is not a question just about reduce but about the whole construct - there are two lambdas, one reduce and I do not know how the expression evaluates to. What does underscore stand for, how does it work, etc)

Can somebody take the 2 minutes that can explain the whole construct here ?

S.S.Prabhu
  • 99
  • 10
  • 1
    I think the issue here is understanding `reduce`, not the lambda. Do you understand what `reduce` is doing? – DeepSpace Nov 13 '19 at 14:03
  • Yes DeepSpace, I believe you are right. However, considering am new to Python so I may have gaps in understanding Lambda (am unable to split it down into individual parameters how the nested lambdas take and what arguments reduce takes, etc, etc) and Reduce functions as well as how this lambda expression works overall. Could you explain further ? – S.S.Prabhu Nov 13 '19 at 14:10
  • (Thanks xnkr, for the suggestion on a reduce function explained and yes, am able to understand that and it was part of the self training I did but what I do not understand is how this works for lambda x, _ : x+[x[-1]+x[-2]],range(n-2), [0, 1]. It is not a question just about reduce but about the whole construct - there are two lambdas, one reduce and I do not know how the expression evaluates to. What does underscore stand for, how does it work, etc) Can somebody take the 2 minutes that can explain the whole construct here ? – S.S.Prabhu Nov 13 '19 at 14:20

1 Answers1

5

Break it down piece by piece:

lambda n: - defines a function that takes 1 argument (n); equivalent to an anonymous version of: def somefunc(n):

reduce() - we'll come back to what it does later; as per docs, this is a function that operates on another function, an iterable, and optionally some initial value, in that order. These are:

  1. A) lambda x, _: - again, defines a function. This time, it's a function of two arguments, and the underscore as the identifier is just a convention to signal we're not gonna use it.

    B) X + [ <stuff> ] - prepend some list of stuff with the value of the first arg. We already know from the fact we're using reduce that the arg is some list.

    C) The <stuff> is x[-1] + x[-2] - meaning the list we're prepending our X to is, in this case, the sum of the last two items already in X, before we do anything to X in this iteration.

  2. range(n-2) is the iterable we're working on; so, a list of numbers from 1 to N-2. The -2 is here because the initial value (in 3) already has the first two numbers covered.

  3. Speaking of which, [0, 1] is our predefined first two starting values for X[-2], X[-1].

  4. And now we're executing. reduce() takes the function from (1) and keeps applying it to each argument supplied by the range() in (2) and appending the values to a list initialized as [0, 1] in (3). So, we call I1: [0, 1] + lambda 0, [0, 1], then I2: I1 + lambda 1, I1, then I3: I2 + lambda 2, I2 and so on.

jkm
  • 704
  • 4
  • 7
  • Thanks user8407600, for the details. I appreciate your reply in detail. Couple of quick questions for my understanding of the concepts.. I remember range starts from 0 (i.e.,. range(10) gives [0,1,...,9]) right ? And 2nd question is : Is x an array (list) or element ? so will x+x[-1]+x[-2] evaluate to appending two items to list x ? – S.S.Prabhu Nov 13 '19 at 15:59
  • Range does start at 0 if you pass only one arg; with more, you can specify both start and stop. Doesn't matter in this case, because here it just defines the length of the output list. X is a list; more generally, it's the aggregate result of all the previous iterations of reduce(). Written as X+X[-1]+X[-2], it would indeed be a double-append. – jkm Nov 13 '19 at 16:08