python课堂整理14---函数式编程

一、分类

当下主流的编程方法大体分为三类

1. 面向过程

2. 函数式

3. 面向对象

二、函数式编程:函数式 = 编程语言定义的函数 + 数学意义的函数

特征:1. 不可变数据

   2. 第一类对象

3. 尾调用优化(尾递归)

例一、不可变:不用变量保存状态,不修改变量

#非函数式

a = 1
def test1():
    global a
    a += 1
    return a
b = test1()
print(b)

#函数式

n = 1
def test2(n):
    return n + 1
print(test2(2))
print(n)例

例二、第一类对象:函数即变量

1. 函数名可以当作参数传递

2. 返回值可以是函数名

def foo(n):
    print(n)
def bar(name):
    print(‘my name is %s‘%name)

foo(bar(‘dabai‘))

def handle():
    print(‘from hamdle‘)
    return handle
h = handle()
h()
print(h)   #打印handle的内存地址

def test1():
    print(‘from test1‘)
def test2():
    print(‘from test2‘)
    return test1()  #return了test1的返回值

a = test2()
print(a)

三、尾调用优化

尾调用的关键就在于是在函数的最后一步去调用别的函数,那么在最后一步调用有何好处,根据函数即变量的定义,定义a 函数,a 内调用函数b,b内调用函数c,在内存中会形成一个调用记录,又称调用帧(call frame),用于保存调用位置和内部变量等信息,即a-->b-->c,直到c返回结果给b,c的调用记录才会消失,b返回给a,b的调用记录消失,a返回结果,a的调用记录消失,所有的调用记录都是先进后出,形成一个调用栈(call stack)

尾调用由于是函数的最后一步操作,所以不需要保留外层函数的调用记录,因为调用位置、内部变量等信息都不会再用到了,只要直接用内层函数的调用记录,取代外层函数的调用记录就可以了。

def bar(n):
    return n
def foo(x):
    return bar(x)
print(foo(3))

#foo(3)就等于bar(3),也就是说,foo在最后一步调用了bar,然后foo的调用记录就清除了,

剩下得就是bar自己得事情了,所有内存里永远只保留一个调用记录

#函数bar在foo内为非尾调用

def bar(n):
    return n
def foo(x):
    y = bar(x)
    return y
a = foo(3)
print(a)

#函数bar在foo内为非尾调用

def bar(n):
    return n
def foo(x):
    return bar(x) + 1
a = foo(3)
print(a) 

由递归转化为尾递归:

下面代码是一个阶乘函数,计算n的阶层,最多需要保留n个调用记录

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

print(fact(5))

#如果改为尾递归,只保留一个记录

def fact(n, m):
    if n == 1:
        return m
    return fact(n - 1 , n * m)
print(fact(5, 1))

原文地址:https://www.cnblogs.com/dabai123/p/11063835.html

时间: 2024-10-12 04:01:03

python课堂整理14---函数式编程的相关文章

PYTHON修饰器的函数式编程

转自:http://coolshell.cn/articles/11265.html Python修饰器的函数式编程 Python的修饰器的英文名叫Decorator,当你看到这个英文名的时候,你可能会把其跟Design Pattern里的Decorator搞混了,其实这是完全不同的两个东西.虽然好像,他们要干的事都很相似--都是想要对一个已有的模块做一些"修饰工作",所谓修饰工作就是想给现有的模块加上一些小装饰(一些小功能,这些小功能可能好多模块都会用到),但又不让这个小装饰(小功能

Python进阶(迭代,函数式编程,Collections类)

PYTHON进阶 PYTHON迭代 @生成器(Generator) 列表生成器产生的列表很占用内存空间,我们每次在计算使用的时候都是对单个元素进行操作,这样其它元素占用的空间就白白浪费了.所以如果列表内的元素可以按照某种算法推算出来,这样我们就可以在循环过程中不断的推算下一个元素(一次只推算一个),从而避免创建完整的列表而占用大量内存. 在Python中我们把一边循环一边计算的机制称为生成器:generator. 生成器创建的语法 列表生成器中括号[]包裹改为小括号()包裹 # 列表生成器 da

Python学习十一:函数式编程

这也是我第一接触函数式编程这个概念,并不知道是干嘛的?好奇心驱使下学习了一下,有了大致的了解: 函数式编程自己的理解:就跟说话一样写程序,这个程序写出来可以直白的告诉人是要干嘛的. 以下是我读到的关于函数式编程的文章的描述: 函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数![1] 函数式编程的准则:不依赖于外部的数据,而且也不改变外部数据的值,而是返回一个新的值给你.[2] 函数式编程的理念:把函数当成变量来用,关注于描述问题而不是怎么实现,这样可以让代码更易

python笔记三:函数式编程

1.概念: 函数式编程就是一种抽象程度很http://i.cnblogs.com/EditPosts.aspx?opt=1高的编程范式,纯粹的函数式编程语言编写的函数没有变量,因此,任意一个函数,只要输入是确定的,输出就是确定的,这种纯函数我们称之为没有副作用.而允许使用变量的程序设计语言,由于函数内部的变量状态不确定,同样的输入,可能得到不同的输出,因此,这种函数是有副作 用的. 函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数!Python对函数式编程提供部

[原创]Python入门学习之函数式编程

一 前言 初次接触函数式编程是在学习分布式计算的时候,那时候对map/reduce是不明觉厉,也没有懂多少原理方面的东西.Python中的函数式编程也算是初步了解一下map/reduce.所谓函数式编程,本质上是可以归结为面向过程的程序设计,但是它的思想很接近数学计算.它比一般的编程范式要更抽象,而且纯粹的函数式编程语言编写的函数是没有变量的,只要确定了输入,那也就确定了输出.它的另外一个特点就是把函数本身作为参数传入到另一个函数中,允许返回一个函数. 二 高阶函数(High-order Fun

python面向过程与函数式编程

周六闲暇的午后,看到博客园众多大神的技术贴.作为一个什么都不懂的小学生,也开通了自己的博客,以后可以对外装×成伪大神了.第一篇记录下今天下午学的python基础: 1.面向过程编程:在python中,所说的过程其实和函数差别不大,也需要def进行定义,但是过程是没有返回值的. def guocheng(): print('我是过程') 上面定义的就是一个过程,没有返回值,只有函数内部的相关逻辑. 调用上面的过程:a=guocheng(),这样即可调用,如果在面板上打印a,会显示NONE,因为过程

Python学习笔记五函数式编程(一)

参考教程:廖雪峰官网https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000 函数式编程 一.高阶函数 所谓高阶函数就是函数可以以另外一个函数作为参数. 首先需要了解在Python中变量是可以指向函数的,如下例子: >>> abs(-5) 5 >>> f=abs >>> f <built-in function abs> >&

python学习笔记(四) - 函数式编程

一. 高阶函数 高阶函数:把函数作为参数传入,这样的函数称为高阶函数,函数式编程就是指这种高度抽象的编程范式 def add(x, y, f): return f(x) + f(y) print add(-5, 6, abs) # 11 二.返回函数 aaa 三.匿名函数 aaa 四.装饰器 aaa 五.偏函数 aaa

Python基础函数之函数式编程

一. 匿名函数 匿名函数就是不需要显示的指定函数,只要运行过一次后就立马释放内存空间. 主要表现形式为: lambda 形参:具体功能 def calc(n): return n**n print(calc(10)) #换成匿名函数 calc = lambda n:n**n print(calc(10)) 你也许会说,用上这个东西没感觉有毛方便呀, ....呵呵,如果是这么用,确实没毛线改进,不过匿名函数主要是和其它函数搭配使用的呢,如下 res = map(lambda x:x**2,[1,5