So on internet they solve using:
from functools import reduce
fib = lambda n: reduce(lambda x, _: x+[x[-1]+x[-2]],range(n-2), [0, 1])
print(fib(5))
I don't understand what's the use of underscore _ and actually how this range(n-2) is working inside program
fib = lambda n: ...
creates a one liner lambda function and assigns it to fib
. Now, fib
is a callable like a function e.g. fib(5)
.
reduce
accepts 3 params: reduce(function, iterable, [, initializer])
.
lambda x, _: x+[x[-1]+x[-2]]
is your function
. It concats current x
sequence to a single-element sequence of sum of last and second last elements in the sequence x
(see table below).
range(n-2)
is iterable
which generates a sequence of numbers [0,1,2]
for n=5
.
[0, 1]
is the initial sequence to start with i.e. first 2 fixed numbers in fib sequence.
_
is used as second argument of function
which is ignored. It is a convention to use _
for ignored argument in a functional program. The second argument receives one value from iterable
for each run i.e. 0
, 1
, & 2
.
Dry run for n=5
--------------------------------------------------------------
range(n-2) x _ x+[x[-1]+x[-2]] output
--------------------------------------------------------------
0 [0,1] 0 [0,1]+[0+1] [0,1,1]
1 [0,1,1] 1 [0,1,1]+[1+1] [0,1,1,2]
2 [0,1,1,2] 2 [0,1,1,2]+[1+2] [0,1,1,2,3]
Note: [0,1] + [0+1]
is list concatenation of [0,1]
and [1]