高阶函数与递归

什么是高阶函数?

  变量可以指向函数,函数的参数能接收变量,函数可以接收另一个函数作为参数,我们称为高阶函数。

def calc(x):
    return x*x
f = calc
f = lambda x:x*x  #匿名函数

变量指向函数

x = 10
def calc(x):
    return x*x

函数接收变量

def func(x,y):
    return x + y
def calc(x):
    return x
f = calc(func)
print(f(5,6))

函数接收另一个函数当做参数

只要满足以下任意一个条件就是高阶函数:

  1,接收一个或多个函数作为输入(参数)。

  2,return返回另一个函数。

递归

  递归,就是函数在运行中调用自己。

def recursion(n):
    print(n)
    recursion(n+1) #每执行一次都会调用一次自己,该函数相当于死循环
recursion(1)

递归

出现的效果就是,这个函数在不断的调用自己,每次调用就n+1,相当于循环了。

通俗来说,每个函数在调用自己的时候还没有推出,占内存多了或导致崩溃。本质是因为函数调用是通过栈(stack)这种数据结构实现的。每当进入一个函数调用栈就会加一层栈帧,每次函数返回,栈就会建一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。

函数调用的栈结构:

递归的特点

让10不断除以2,直到0为止。(调用多少次,结束就也要结束多少次)

# def calc(n):
#     val = n//2
#     print(val)
#     if val ==0:
#         return 1
#     calc(val)
#     print(val) #按照反序一次一次返回
# calc(10)

def calc(n):
    print(n)
    if n //2 >0:
        calc(n//2)
    print(n)
calc(10)

10除以2递归

求阶乘

任何大于1的自然数n阶乘表示方法:n!=1*2*3*4*5*6*...*n  或者 n!=n*(n-1)!即举例:4!=4*3*2*1=24

def factorial(n):
    if n ==1:
        return 1
    return n*factorial(n-1)
print(factorial(5))

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

阶层

递归:a,自己调用自己。b,有结束条件   两个必须满足

尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。

def fact(n):
    return fact_iter(n, 1)

def fact_iter(num, product):
    if num == 1:
        return product
    return fact_iter(num - 1, num * product)
print(fact(5))
print(fact_iter(5,1))

可以看到,return fact_iter(num - 1, num * product)仅返回递归函数本身,num - 1num * product在函数调用前就会被计算,不影响函数调用。

fact(5)对应的fact_iter(5, 1)的调用如下:

===> fact_iter(5, 1)
===> fact_iter(4, 5)
===> fact_iter(3, 20)
===> fact_iter(2, 60)
===> fact_iter(1, 120)
===> 120尾递归调用时,如果做了优化,栈不会增长,因此,无论多少次调用也不会导致栈溢出。

小结

使用递归函数的优点是逻辑简单清晰,缺点是过深的调用会导致栈溢出。

针对尾递归优化的语言可以通过尾递归防止栈溢出。尾递归事实上和循环是等价的,没有循环语句的编程语言只能通过尾递归实现循环。

Python标准的解释器没有针对尾递归做优化,任何递归函数都存在栈溢出的问题。

原文地址:https://www.cnblogs.com/chris3201/p/8993957.html

时间: 2024-11-09 04:03:18

高阶函数与递归的相关文章

Python学习笔记八:文件操作(续),文件编码与解码,函数,递归,函数式编程介绍,高阶函数

文件操作(续) 获得文件句柄位置,f.tell(),从0开始,按字符数计数 f.read(5),读取5个字符 返回文件句柄到某位置,f.seek(0) 文件在编辑过程中改变编码,f.detech() 获取文件编码,f.encoding() 获取文件在内存中的编号,f.fileno() 获取文件终端类型(tty.打印机等),f.isatty() 获取文件名,f.name() 判断文件句柄是否可移动(tty等不可移动),f.seekable() 判断文件是否可读,f.readable() 判断文件是

11.高阶函数(匿名/*递归/函数式)对象编程基础

高阶函数匿名函数匿名函数存在的情况:内置函数函数式编程递归函数式编程面向对象的程序设计类:实例:OOP类的名称空间/对象的名称空间 高阶函数 匿名函数 lambda x:x+y #return x+y 定义标志/参数(形式类似函数传参)/跟表达式(返回) 匿名函数存在的情况: 执行完这行之后,如果没有被赋值给别的变量 其引用计数为0,就会被内存垃圾回收机制清空 from functoolimport reduce sorted 倒序并且生成新列表/sort是仅仅倒序 map 映射 reduce

Python 3 学习笔记(五)----变量、递归和高阶函数

一.变量 1.在子程序中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量.2.全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序.3.当全局变量与局部变量同名时:在定义局部变量的子程序内,局部变量起作用:在其它地方全局变量起作用. 1 country = "China" #全局变量 2 3 def change_name(name): 4 global country #如果要在函数中更改全局变量,只有一种方法在函数中声明global+变量名.永远不要用这种方法

python第三天学习复习,集合set,文件操作,函数(普通函数,递归,高阶函数),字符编码和解码

三元运算 age = 23 #就是if else的简单写法 a = age if age < 20 else 25 集合 set #集合是无序切不重复的, #当对列表去重复的时候,可以直接使用 set(list),就将list转为set,并去除中间重复的 list = [1,2,3,4,5,5,6,7,8,9,1] s = set(list) 运行结果:可以发现将 list中重复的去掉,并且类型变成set,再使用list(set),转为list 集合操作 # Author:zylong set1

高阶函数-递归

1.高阶函数 1.1高阶函数定义 变量可以指向函数,函数的参数能接受变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称为高阶函数.只要满足以下任意一个条件,即是高阶函数1.接收一个或多个函数作为输入2.return返回另外一个函数 #!/usr/bin/env python # -*- coding:utf-8 -*- # Author: vita def add(x, y, func): return func(x) + func(y) res = add(3, -6, abs) p

Haskell高阶函数

Haskell functions can take functions as parameters and return functions as return values. A function that does either of those is called a higher order function. Higher order functions aren't just a part of the Haskell experience, they pretty much ar

高阶函数之函数作为参数

SICP 1.3.1  Procedures as Arguments,说明高阶函数之函数作为参数的原因:若干个函数拥有相似的算法或代码结构,对此加以抽象. (define (sum-integers a b) (if (> a b) 0 (+ a (sum-integers (+ a 1) b)))) (define (pi-sum a b) (if (> a b) 0 (+ (/ 1.0 (* a (+ a 2))) (pi-sum (+ a 4) b)))) 于是: 清单1: (defi

Day3-递归函数、高阶函数、匿名函数、内置函数

一.递归函数 定义:函数内部可以调用其它函数,如果调用自身,就叫递归. 递归特性: 1.必须有结束条件退出: >>> def calc(n): ... print(n) ... return calc(n+1) ... >>> calc(0) 0 1 ... 998 RecursionError: maximum recursion depth exceeded while calling a Python object 分析: 没有结束条件,超过最大递归次数999次后

Scala 高阶函数(high-order function)剖析

Scala 是一种函数式编程语言,也就是说每一个函数都是一个值.Scala 有很简洁的语法用于定义匿名函数.curry 化函数(curried function).应用函数.偏函数以及嵌套函数等.函数式编程由数学函数演变得来,包含大量诸如串联与并联.组合与分离.协变与逆变等一系列概念.本文将就如何实现高阶函数进行阐述,其他部分内容不进行深究. 类型参数化协变与逆协变 类型参数化(type parameterization)由类型协变性(Type variance)补充构成,类型协变性的机制则是在