循环、分支...都可以在Python中用函数实现! | 函数式编程,打开另一个世界的大门

编程界有一位传奇人物——王垠,介绍一下他的退学经历,对,你没听错,退!学!经!历!:

  • 2006年,从清华大学计算机系退学,在水木社区BLOG上发表了《清华梦的粉碎--写给清华大学的退学申请》一文,此时离博士毕业还差一年;
  • 2008年,从美国康奈尔大学计算机系退学,在网上发表《Cornell 感受》;
  • 2012年,从印第安纳大学伯明顿分校计算机系退学,以一篇文章《对博士学位说永别》,彻底告别了学生生涯。
  • 这里插一句,就在我写这篇文章的时候(写的时间有点久...),王垠的博客又更新了一篇文章《微软的秘密离职协议》,文中描述了他离职微软的撕逼过程......

更传奇的是他的「40行代码」。据说,他层公开过一段40行的代码,并宣称这是他上半生最重要的杰作,曾经耗费顶级专家多年的研究,知乎上有专门的讨论:

https://www.zhihu.com/question/20822815

从这几个经历,我们大概可以推测王垠这个人:

  • 是一位程序大牛;
  • 他追求的 是某种我们凡人无法感受到的东西;
  • 他很能写,不论是代码还是段子。

这么一位程序员大牛+重磅写手,在网络上写了几篇深远影响的文章:

其中有一篇跟本文的要说的内容有关——《面向对象编程和函数式编程的问题出在哪里》,这篇文章他将面向对象编程,和函数式编程并列,对两种编程进行了比较和点评。文中的重点,是批评了纯函数式编程

文本不讨论这篇文章,主要是聊一聊到底什么是「函数式编程」。

点进来的很多同学,应该和我一样,都是数据/统计出身,捣鼓比较多的是SAS/ R,后来转向Python,发现了lambda、map、reduce这些「奇怪」的东西。这说明,你已经开始了函数式编程的体验。

为了呈现函数式编程的概念,我们将编程思维分成「平凡的世界」和「函数的世界」,从实例对比中了解函数式编程。

另外,由于Python是一种通用性编程语言,它支持函数式编程,因此本文的代码实例都用Python来举例。

在「平凡的世界」中,我们一般都是怎么写代码的?以前学SAS的时候看到过一句话:

一门编程语言,只要能实现分支和循环,就能够完成几乎所有的运算。

这么说来,我们在平时编程中无外乎用下面这几个语句:

  • 分支:if...elif...
  • 循环:for/ while/ do...loops
  • 其他还有赋值、函数定义def等。

而在「函数式编程」的世界中,这些将全部用函数来实现!!比如:

匿名函数lambda、Map函数、Reduce函数。

基本上,这几个函数就可以实现任意的Python程序了!我们通过实例来认识一下:

匿名函数:lambda表达式

lambda表达式,又叫匿名函数,它用来创建一个函数,取代def这个功能。

比如,定义一个函数,返回两个参数x+y的值, 在「平凡的世界」里,我们这么写: def add(x, y): return x + y print add(1,2) 用lambda表达式,我们可以这么写: add=lambda x,y : x + y print add(1,2)

因此,lambda表达式的格式提炼如下:

func = lambda 参数: 调用参数的表达式

Map函数

Map函数,是用函数的方式来实现一个循环运算,类似for的功能:

比如,现在有一个list=[2, 4, 6, 7, 8],想对里面每个元素进行平方,生成一个新的new_list。 在「平凡的世界」里,我们这么写: list = [2, 4, 6, 7, 8] new_list = [ ] for i in list: new_list.append(i*i) 返回的结果是: [4, 16, 36, 49, 64] 用Map函数,我们这么写: sqr = lambda a: a*a print map(sqr, [2, 4, 6, 7, 8]) 返回的结果、: [4, 16, 36, 49, 64]

因此,Map函数的使用格式提炼如下:

new_list = Map(func, list),将list中每个元素都进行一个func函数的计算,生成一个新的list

Reduce函数

这个我用的比较少,简单介绍一下,它是对一个数组的元素,进行从左到右进行一个累计的计算。

比如,有一个list=[2, 4, 6, 7, 8],现在相对所有元素从左到右进行相乘 在「平凡的世界」里,我们这么写: result = 1 for i in [2, 4, 6, 7, 8]: result = result * i print result 返回结果为:2688 用reduce函数,我们这么写: conplus = lambda a,b: a*b print reduce(conplus , [2, 4, 6, 7, 8]) 返回结果为2688.

因此,Reduce函数的使用格式提炼如下:

result = Map(func, [a1, a2, a3...]),将list中元素,从左到右进行func计算,先计算func(a1, a2), 在计算func(func(a1, a2), a3).....

这些函数相互搭配使用,据说(我也不敢肯定)能代替任务的Python程序!不管怎样,我们大概知道了「函数式编程」这个概念:

它用一系列函数取解决问题,代码简洁,没有循环体,也不用生成各种倒来倒去的临时变量。

但是,回到开篇王垠的批判文章,「函数式编程」有哪些缺点?下次有机会再说。

- END -

本文分享自微信公众号 - 数说工作室(shushuojun)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-05-24

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏python学习指南

Python自建collections模块

本篇将学习python的另一个内建模块collections,更多内容请参考:Python学习指南 collections是Python内建的一个集合模块,提...

374100
来自专栏python学习指南

Python网络_UDP编程

本章将介绍UDP编程,更多内容请参考:Python学习指南 TCP是建立可靠连接,并且通信双方都可以以流的形式发送数据。相对TCP连接,UDP则是面向无连接的...

39460
来自专栏漏斗社区

CTF|玩转RSA加密算法(一)

RSA是一种非对称加密算法,它由 公钥(n/e),私钥(n/d),明文M和密文C组成。我们做CTF题目时,一般题目中会给出公钥和密文让我们推出对应的私钥或者明文...

96490
来自专栏漏斗社区

CTF| 你想要的RSA解题技巧(二)

上一期已经给大家分享了RSA的基本解题思路,总结如下,本期带来几种复杂的RSA题目解法。 ? 以上都是基本解法,基于n能够分解的前提下进行的解法,但是当题目n的...

47180
来自专栏python学习指南

Python网络_TCP/IP简介

本章将介绍tcp网络编程,更多内容请参考:Python学习指南 Socket是网络编程的一个抽象概念,通常我们用一个Socket表示"打开了一个网络连接",而...

37390
来自专栏漏斗社区

工具 | w3af系列安装篇(一)

W3af是一个基于Python的Web应用扫描器,本期我们将来唠一唠w3af的安装和使用。 ? 在windows上安装 ‍‍‍‍‍ 官网的最新版本已经不提...

44070
来自专栏新智元

【比竞争对手快3倍】微软官方发布CNTK 2.0,增加 Python 和 Keras 支持

【新智元导读】微软今天发布了深度学习工具包CNTK的2.0版本,新版本增加了支持 Keras 的 CNTK 后端,Java API,模型评估的 Spark 支持...

45480
来自专栏python学习指南

Python_TCP/IP简介

本篇将开始介绍Python的网络编程,更多内容请参考:Python学习指南 自从互联网诞生以来,现在基本上所有的程序都是网络程序,很少有单机版的程序了。 计算...

38780
来自专栏漏斗社区

工具| 手把手教你制作信息收集器之端口扫描

本期任务:使用python脚本实现端口扫描。 准备工具:选项分析器:optparse;网络库:socket 问题引入 1. 端口扫描器扫描效果如何? ...

38160
来自专栏漏斗社区

漏洞|74cms 3.6 前台SQL注入+Python脚本小练习

最近有个74cms v4.2.3任意文件下载的漏洞,本来想试着和74cms 3.6 前台SQL注入漏洞结合下然后取出QS_pwdhash的值进行MD5碰撞,可...

593100

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励