函数式编程

函数与函数式编程

落花浮王杯 提交于 2019-12-02 18:06:46
1 函数 函数定义:函数是逻辑结构化和过程化的一种编程方法。 函数式编程定义:先定义一个数学函数,然后按照这个数学模型用编程语言去实现它。 过程定义:过程就是简单特殊没有返回值的函数。 函数式编程实现的目的:可以使程序员写出更为精确和高效的代码。 函数式编程的优势:在以函数式风格写代码时,函数应该设计成没有其他副作用。函数接收参数并生成输出而不保留任何状态或修改任何不反映在返回值中的值。这种理想方式的函数可以被当成纯函数式函数。 非纯函数: def test1(mylist): mylist.pop(-1) 纯函数: def test2(mylist): return mylist[:-1] Python中函数定义方法: def test(x): #def 定义函数的关键字,test是函数名,()内可定义形参 “the function definitions” #文档描述 x+=1 #泛指代码块或程序处理逻辑 Return x #定义返回值 函数优势: 1、代码可重用 2、保持一致性 3、可扩展性 生成器 生成器( generator)是对象,在每次调用它的next()方法时返回一个值,直到它抛出StopIteration。 操作:创建一个生成器,只需要写一个普通的包含 yield语句的python函数。 原理: python检测对yield的使用并将这个函数标识为一个生成器

js使用函数式编程改造循环

蓝咒 提交于 2019-12-02 16:19:04
For 循环的设计思想深受可变状态与副作用的影响,不过函数式编程中认为可变状态与副作用是导致潜在错误与不可预测性的罪魁祸首,是应该尽力避免的模式。众所周知,使用全局状态会污染局部代码,而同样的局部状态同样会导致与全局状态一样的问题,只不过因为局部状态的影响被限制在较小的影响范围内,因此不像全局状态那样的突兀。允许可变的状态也就意味着变量可能因为未知的原因被改变,开发者可能要花费数小时的时间去定位到底是哪一段代码修改了这个变量值。在过去的开发岁月里,我就是因为这样变秃了,却似乎没有变强。另一方面,任何修改除了作用域内变量值的函数都被称为有副作用的函数。典型的譬如修改全局变量、读入键盘输入、调用远程 API 、写入磁盘等等。副作用的功效强大,我们应该尽可能地将其封装与控制在一定范围内。大道理就回顾到这里,下面我们直接看下代码: const cats = [ { name: 'Mojo', months: 84 }, { name: 'Mao-Mao', months: 34 }, { name: 'Waffles', months: 4 }, { name: 'Pickles', months: 6 } ]; const kittens = []; //典型的 for 循环用法 for (const i = 0; i < cats.length; i++) { if (cats[i]

day3 函数

爷,独闯天下 提交于 2019-12-02 06:32:30
1. 函数基本语法及特性 2. 参数与局部变量 3. 返回值 嵌套函数 4.递归 5.匿名函数 6.函数式编程介绍 7.高阶函数 8.内置函数 温故知新 1. 集合 主要作用: 去重 关系测试, 交集\差集\并集\反向(对称)差集 >>> a = {1,2,3,4} >>> b ={3,4,5,6} >>> a {1, 2, 3, 4} >>> type(a) <class 'set'> >>> a.symmetric_difference(b) {1, 2, 5, 6} >>> b.symmetric_difference(a) {1, 2, 5, 6} >>> >>> >>> a.difference(b) {1, 2} >>> a.union(b) {1, 2, 3, 4, 5, 6} >>> a.issu a.issubset( a.issuperset( >>> a.issubset(b) False 2. 元组 只读列表,只有count, index 2 个方法 作用:如果一些数据不想被人修改, 可以存成元组,比如身份证列表 3. 字典 key-value对 特性: 无顺序 去重 查询速度快,比列表快多了 比list占用内存多 为什么会查询速度会快呢?因为他是hash类型的,那什么是hash呢? 哈希算法将任意长度的二进制值映射为较短的固定长度的二进制值

Python的函数式编程及基本函数

限于喜欢 提交于 2019-12-02 04:42:54
函数式编程 函数式编程并不是在使用Python时需要考虑的首要问题,它的主要作用在于写出更为精确和高效的代码。 用函数式的风格写代码时,函数应该设计成没有其它副作用,也就是所谓的纯函数:函数接收参数并生成输出而不保留任何状态或修改任何不反映在返回值中的内容。 # 非函数式 a = 0 def increment1(): global a a += 1 # 函数式 def increment2(a): return a + 1 lambda 匿名函数,一般用来给map、filter等服务,即用即扔,或者作为回调函数,传递给某些应用。 lambda args: expression 冒‍号左边是参数,右边是表达式,并将结果作为返回‍值。 map map接受一个方法和一个集合作为参数,以集合中的每一个元素作为参数传入方法,然后把返回值插入到新创建的集合中,最后返回那个新集合。 >>> map(lambda s: s * 2, [1,2,3,4,5])[2, 4, 6, 8, 10] map也可以接收多个集合作为参数,这个时候,会从多个集合中依次取出对应元素组成元组传递给方法,再将执行结果插入到新的集合中并返回该集合。如果多个集合长度不一致,会以None补上。当然,集合的个数需要与方法参数的个数一致。 >>> plus = lambda x,y : (x or 0) + (y or 0)

Python3基础-函数式编程

*爱你&永不变心* 提交于 2019-12-01 13:12:45
1、高阶函数【函数式编程】 函数的传入参数是一个函数名 函数的返回值是一个函数名 特性: #不可变数据:不用变量保存状态,不修改变量 #非函数式 a=1 def inc_test1(): global a a += 1 #赋值 ,修改变量 return a inc_test1() print(a) #函数式 a = 1 def inc_test1(n): return n+1 #不修改变量 print(inc_test1(2)) print(a) #测试点:传入参数是一个函数名 test1 def test(n): #n=test1 print(n) def test1(name): print('my name is %s'%name) test(test1) #将test1函数名作为实参传入 """ 执行结果 <function test1 at 0x03979738> """ #测试点:传入参数是一个函数名 test1() def test(n): #n=test1 print(n) def test1(name): print('my name is %s'%name) test(test1('susu')) """ 执行结果 my name is susu None """ #测试点 返回值包含函数名称 def test(): print("测试函数式") return

python函数式编程

人走茶凉 提交于 2019-12-01 11:43:39
一、高阶函数 1、变量可以指向函数 >>> f = abs >>> f(-10) 10 2、函数名也是变量,可以被赋值,但一般别这么干  3、传入函数 参数是一个函数---高阶函数 def add(x, y, f): return f(x) + f(y) >>>add(-5, 6, abs) 11    4、map / reduce ①map(函数名,Iterable) 函数作用到Iterable的每一个元素上,返回一个Iterator >>> def f(x): ... return x * x ... >>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9]) >>> list(r) [1, 4, 9, 16, 25, 36, 49, 64, 81] >>> list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9])) ['1', '2', '3', '4', '5', '6', '7', '8', '9'] ②reduce(函数,序列) reduce 把结果继续和序列的下一个元素做累积计算   reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)  >>> from functools import reduce>>> def fn(x, y):... return x

javascript函数式编程简单介绍

点点圈 提交于 2019-12-01 06:55:31
函数式编程在前端已经成为了一个热门的话题,近几年很多的应用程序代码库里大量使用着函数式编程思想。这里对JavaSctipt中的函数式编程做一个简单介绍。 什么是函数式编程 函数式编程是一种编程范式,主要是利用函数把运算过程封装起来,通过组合各种函数来计算结果。函数式编程意味着开发者可以在更短的时间内编写具有更少错误的代码。 函数式编程的简单例子 假设要把一个字符串转换成每个单词首字母大写,可以这样来实现: var string = 'i do like yanggb'; var result = string .split(' ') .map(v => v.slice(0, 1).toUpperCase() + v.slice(1)) .join(' '); 在这个例子中,为了得到想要的结果,先调用split()方法将字符串转换成数组,然后再调用map()方法把各个元素的首字母转换成大写,最后再调用join()方法把数组转换成字符串。这里的整个过程就是join(map(split(str))),体现了函数式编程的核心思想:通过函数对数据进行转换。 函数式编程的两个基本特点 通过上面的例子可以得到函数式编程有两个基本特点: 1.通过函数来对数据进行转换。 2.通过串联多个函数来求最终结果。 与 命令式编程、 声明式编程的对比 这里简单对比下函数式编程与命令式编程、声明式编程的区别。

JavaScript 中的函数式编程实践

我与影子孤独终老i 提交于 2019-12-01 06:10:50
基础知识 函数式编程简介 说到函数式编程,人们的第一印象往往是其学院派,晦涩难懂,大概只有那些蓬头散发,不修边幅,甚至有些神经质的大学教授们才会用的编程方式。这可能在历史上的某个阶段的确如此,但是近来函数式编程已经在实际应用中发挥着巨大作用了,而更有越来越多的语言不断的加入诸如 闭包 , 匿名函数 等的支持,从某种程度上来讲,函数式编程正在逐步“同化”命令式编程。 函数式编程思想的源头可以追溯到 20 世纪 30 年代,数学家阿隆左 . 丘奇在进行一项关于问题的可计算性的研究,也就是后来的 lambda 演算。lambda 演算的本质为 一切皆函数 ,函数可以作为另外一个函数的输出或者 / 和输入,一系列的函数使用最终会形成一个表达式链,这个表达式链可以最终求得一个值,而这个过程,即为计算的本质。 然而,这种思想在当时的硬件基础上很难实现,历史最终选择了同丘奇的 lambda 理论平行的另一种数学理论:图灵机作为计算理论,而采取另一位科学家冯 . 诺依曼的计算机结构,并最终被实现为硬件。由于第一台计算机即为冯 . 诺依曼的程序存储结构,因此运行在此平台的程序也继承了这种基因,程序设计语言如 C/Pascal 等都在一定程度上依赖于此体系。 到了 20 世纪 50 年代,一位 MIT 的教授 John McCarthy 在冯 . 诺依曼体系的机器上成功的实现了 lambda 理论

漫谈递归和迭代

亡梦爱人 提交于 2019-12-01 04:59:06
先讲个故事吧。 从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?“从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?‘从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?……’”。 这个故事永远也讲不完,因为没有递归结束条件。老师讲递归时总是说,递归很简单,一个递归结束条件,一个自己调用自己。如果递归没有结束条件,那么就会无限递归下去。在编程的时候,没有递归结束条件或者递归过深,一般会造成栈溢出。 下面这个函数,可以利用栈溢出来估测栈的大小: 1 void stack_size() 2 { 3 static int call_time = 0; 4 char dummy[1024*1024]; 5 call_time++; 6 printf("call time: %d\n",call_time); 7 stack_size(); 8 } 递归算法一般用于解决三类问题:这个函数定义了1M的局部变量,然后调用自己。栈溢出时会崩溃,根据最后打印出的数字可以算一下栈的大小。 (1)数据的定义是按递归定义的。(Fibonacci函数) (2)问题解法按递归算法实现。(回溯) (3)数据的结构形式是按递归定义的。(树的遍历,图的搜索) 对于求1+2+3+…+n这种问题,大部分人不会用递归方式求解: 1 2 3 4

java8函数式编程--收集器collector

半腔热情 提交于 2019-12-01 03:57:55
java8的stream api能很方便我们对数据进行统计分类等工作,以前我们写的很多统计数据的代码往往是循环迭代得到的,不说别人看不懂,自己的代码放久了也要重新看一段时间才能看得懂。现在,java8吸收了适合科学计算的语言的新特性,提供了stream api,让我们方便并且直观地编写统计代码成为可能。 stream里有一个collect(Collector c)方法,需要传入Collector收集器这个接口。现在就说说这个接口定义的职责。 public interface Collector<T, A, R> { Supplier<A> supplier(); BiConsumer<A, T> accumulator(); BinaryOperator<A> combiner(); Function<A, R> finisher(); Set<Characteristics> characteristics(); } Collector主要定义了容器的类型,添加元素的方法,容器合并的方法还有输出的结果。 supplier就是生成容器,accumulator是添加元素,combiner是合并容器,finisher是输出的结果, characteristics是定义容器的三个属性,包括是否有明确的finisher,是否需要同步,是否有序。 例如: