Python recursive functions

Source: Internet
Author: User
Tags stdin

Inside a function, you can call other functions. If a function calls itself internally, the function is a recursive function.

For example, let's calculate factorial n! = 1 x 2 x 3 x ... x n , which is represented by a function fact(n) , and you can see:

Fact (n) = n! = 1 x 2 x 3 x ... x (n-1) x n = (n-1)! X n = fact (n-1) x n

Therefore, fact(n) can be expressed as n x fact(n-1) , only n=1 need special handling.

So, it fact(n) is written in a recursive way:

def fact(n):    if n==1:        return 1    return n * fact(n - 1)

Above is a recursive function. You can try:

>>> fact(1)1>>> fact(5)120>>> fact(100)93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000L

If we calculate fact(5) , we can see the calculation process according to the function definition as follows:

===> fact(5)===> 5 * fact(4)===> 5 * (4 * fact(3))===> 5 * (4 * (3 * fact(2)))===> 5 * (4 * (3 * (2 * fact(1))))===> 5 * (4 * (3 * (2 * 1)))===> 5 * (4 * (3 * 2))===> 5 * (4 * 6)===> 5 * 24===> 120

The advantage of recursive functions is that they are simple in definition and clear in logic. In theory, all recursive functions can be written in a circular way, but the logic of the loop is not as clear as recursion.

The use of recursive functions requires careful prevention of stack overflow. In the computer, the function call is implemented through a stack (stack) of this data structure, each time into a function call, the stack will add a stack of frames, whenever the function returns, the stack will be reduced by a stack of frames. Because the size of the stack is not infinite, there are too many recursive calls that can cause the stack to overflow. You can try fact(1000) :

>>> fact(1000)Traceback (most recent call last):  File "<stdin>", line 1, in <module>  File "<stdin>", line 4, in fact  ...  File "<stdin>", line 4, in factRuntimeError: maximum recursion depth exceeded

The method of solving recursive call stack overflow is optimized by tail recursion , in fact, the effect of tail recursion and loop is the same, so it is possible to think of the loop as a special tail recursive function.

Tail recursion means that when a function returns, it calls itself, and the return statement cannot contain an expression. In this way, the compiler or interpreter can optimize the tail recursion, so that the recursive itself, regardless of the number of calls, only occupy a stack frame, there is no stack overflow situation.

The above fact(n) function, because of the introduction of the return n * fact(n - 1) multiplication expression, is not a tail recursion. To change to a tail recursion, more code is needed, mainly to pass the product of each step into the recursive function:

def fact(n):    return fact_iter(1, 1, n)def fact_iter(product, count, max):    if count > max:        return product    return fact_iter(product * count, count + 1, max)

As you can see, return fact_iter(product * count, count + 1, max) only the recursive function itself is returned, product * count and count + 1 it is evaluated before the function call, without affecting the function call.

fact(5)The corresponding fact_iter(1, 1, 5) call is as follows:

===> fact_iter(1, 1, 5)===> fact_iter(1, 2, 5)===> fact_iter(2, 3, 5)===> fact_iter(6, 4, 5)===> fact_iter(24, 5, 5)===> fact_iter(120, 6, 5)===> 120

At the end of a recursive call, if optimized, the stack does not grow, so no amount of calls will cause the stack to overflow.

Unfortunately, most programming languages are not optimized for tail recursion, and the Python interpreter is not optimized, so even if the above function is changed to fact(n) tail recursion, it can cause the stack to overflow.

There is a decorator for tail-recursive optimization, you can refer to the source code:

http://code.activestate.com/recipes/474088-tail-call-optimization-decorator/

We'll talk about how to write decorator later. Now, just use this @tail_call_optimized , and you'll be able to calculate it smoothly fact(1000) :

>>> Fact (1000) 4023872600770937735437024339230039857193748642107146325437999104299385123986290205920442084869694048004799886101971960586 3166687299480855890132382966994459099742450408707375991882362772718873251977950595099527612087497546249704360141827809464 6496291056393887437886487337119181045825783647849977012476632889835955735432513185323958463075557409114262417474349347553 4286465766116677973966688202912073791438537195882498081268678383745597317461360853795345242215865932019280908782973084313 9284440328123155861103697680135730421616874760967587134831202547858932076716913244842623613141250878020800026168315102734 1827977704784635868170164365024153691398281264810213092761244896359928705114964975419909342221566832572080821333186116811 5536158365469840467089756029009505376164758477284218896796462449451607653534081989013854424879849599533191017233555566021 3945039973628075013783761530712776192684903435262520001588853514733161170210396817592151090778801939317811419454525722386 5541461062892187960223838971476088506276862967146674697562911234082439208160153780889893964518263243671616762179168909779911903754 0312746222899880051954444142820121873617459926429565817466283029555702990243241531816172104658320367869061172601587835207 5151628422554026517048330422614397428693306169089796848259012545832716822645806652676995865268227280707578139185817888965 2208164348344825993266043367660176999612831860788386150279465955131156552036093988180612138558600301435694527224206344631 7974605946825731037900840244324384656572450144028218852524709351906209290231364932734975655139587205596542287497740114133 4696271542284586237738753823048386568897646192738381490014076731044664025989949022222176590433990188601856652648506179970 2356193897017860040811889729918311021171229845901641921068884387121855646124960798722908519296819372388642614839657382291 1231250241866493531439701374285319266498753372189406942814341185201580141233448280150513996942901534830776445690990731524 332782882698646027898643211390835062170950025973898635542771967428222487575867657523442202075736305694988250879689281627538488633969099598262809561214509 9487170124451646126037902930912088908694202851064018215439945715680594187274899809425474217358240106367740459574178516082 9230135358081840096996372524230560855903700624271243416909004153690105933983835777939410970027753472000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Summary

The advantage of using a recursive function is that the logic is simple and clear, and the disadvantage is that too-deep calls cause a stack overflow.

The language that is optimized for tail recursion can prevent stack overflow by tail recursion. The tail recursion is actually equivalent to the loop, and the programming language without the loop statement can only be looped by the tail recursion.

The Python standard interpreter is not optimized for tail recursion, and there is a stack overflow problem with any recursive function.

Python recursive functions

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.