Explain the recursive functions in Python _python

Source: Internet
Author: User
Tags function definition stdin

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

For example, let's compute the factorial n! = 1 x 2 x 3 x ... x n, represented by a function fact (n), you can see that:

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 represented as N x fact (n-1), and only n=1 requires special handling.

So, 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. Can try:

>>> fact (1)
1
>>> Fact (5)
-
>>> Fact (MB)
9332621544394415268169923885626670049071596826438162146859296389521759999322991560894146397615651828625369792082722375825 1185210916864000000000000000000000000L

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

===> 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 *
===> 120

The advantage of recursive function is that the definition is simple and logic is clear. Theoretically, all recursive functions can be written as loops, but the logic of loops is not as clear as recursion.

Using recursive functions requires attention to prevent stack overflows. In the computer, the function call is through stack (stack) This kind of data structure realizes, whenever enters a function call, the stack will add the stack frame, each time function returns, the stack will reduce one layer stack frame. Because the size of the stack is not infinite, the number of recursive calls can be excessive, resulting in stack 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 fact
runtimeerror:maximum recursion depth exceeded

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

Tail recursion refers to the call itself when the function returns, 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, no matter how many times, only occupy a stack frame, there will be no stack overflow.

The fact (n) function above has introduced a multiplication expression in return n * fact (n-1), so it is not a tail-recursion. To change to the tail recursive way, need a little more code, mainly to 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
    prod UCT return
  fact_iter (product * count, Count + 1, max)

As you can see, return fact_iter (product * count, Count + 1, max) returns only the recursive function itself, and product * count and Count + 1 are evaluated before the function call and do not affect the function call.

Fact (5) the corresponding fact_iter (1, 1, 5) are called as follows:

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

When a tail recursive call is made, if optimized, the stack does not grow, so no matter how many calls it will not cause a stack overflow.

Unfortunately, most programming languages do not optimize for tail recursion, and the Python interpreter does not do optimizations, so even changing the above fact (n) function to tail recursion can result in a stack overflow.

There is a decorator for the 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, you can successfully calculate fact (1000):

>>> Fact (1000) 4023872600770937735437024339230039857193748642107146325437999104299385123986290205920442084869694048004799886101971960586 3166687299480855890132382966994459099742450408707375991882362772718873251977950595099527612087497546249704360141827809464 6496291056393887437886487337119181045825783647849977012476632889835955735432513185323958463075557409114262417474349347553 4286465766116677973966688202912073791438537195882498081268678383745597317461360853795345242215865932019280908782973084313 9284440328123155861103697680135730421616874760967587134831202547858932076716913244842623613141250878020800026168315102734 1827977704784635868170164365024153691398281264810213092761244896359928705114964975419909342221566832572080821333186116811 5536158365469840467089756029009505376164758477284218896796462449451607653534081989013854424879849599533191017233555566021 3945039973628075013783761530712776192684903435262520001588853514733161170210396817592151090778801939317811419454525722386 55414610628921879602238389714760885062768629671466746975629112340824392081601537808898939645182632436716167621791689097799119037 5403127462228998800519544441428201218736174599264295658174662830295557029902432415318161721046583203678690611726015878352 0751516284225540265170483304226143974286933061690897968482590125458327168226458066526769958652682272807075781391858178889 6522081643483448259932660433676601769996128318607883861502794659551311565520360939881806121385586003014356945272242063446 3179746059468257310379008402443243846565724501440282188525247093519062092902313649327349756551395872055965422874977401141 3346962715422845862377387538230483865688976461927383814900140767310446640259899490222221765904339901886018566526485061799 7023561938970178600408118897299183110211712298459016419210688843871218556461249607987229085192968193723886426148396573822 9112312502418664935314397013742853192664987533721894069428143411852015801412334482801505139969429015348307764456909907315 243327828826986460278986432113908350621709500259738986355427719674282224875758676575234422020757363056949882508796892816275384886339690995982628095612145 0994871701244516461260379029309120889086942028510640182154399457156805941872748998094254742173582401063677404595741785160 8292301353580818400969963725242305608559037006242712434169090041536901059339838357779394109700277534720000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Summary

The advantage of using recursive functions is that logic is simple and clear, and the disadvantage is that excessive calls can cause stack overflows.

The language for tail recursion optimization can prevent stack overflow by tail recursion. Tail recursion is actually equivalent to a loop, and a programming language without a looping statement can only implement loops through tail recursion.

The Python standard interpreter does not optimize for tail recursion, and any recursive function has a stack overflow problem.

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.