python 学习笔记——函数式编程

本文为学习慕课网上廖雪峰老师的python进阶课程笔记,其中的题目采自该课程。

  1. 以函数作为参数
import math

def add(x, y, f):
    return f(x) + f(y)
#高阶函数:以函数作为参数
print add(25, 9, math.sqrt)

  • Python数学函数
函数 返回值 ( 描述 )
[abs(x)] 返回数字的绝对值,如abs(-10) 返回 10
[ceil(x)] 返回数字的上入整数,如math.ceil(4.1) 返回 5
[cmp(x, y)] 如果 x < y 返回 -1, 如果 x == y 返回 0, 如果 x > y 返回 1
[exp(x)] 返回e的x次幂(ex),如math.exp(1) 返回2.718281828459045
[fabs(x)] 返回数字的绝对值,如math.fabs(-10) 返回10.0
[floor(x)] 返回数字的下舍整数,如math.floor(4.9)返回 4
[log(x)] 如math.log(math.e)返回1.0,math.log(100,10)返回2.0
[log10(x)] 返回以10为基数的x的对数,如math.log10(100)返回 2.0
[max(x1, x2,...)] 返回给定参数的最大值,参数可以为序列。
[min(x1, x2,...)] 返回给定参数的最小值,参数可以为序列。
[modf(x)] 返回x的整数部分与小数部分,两部分的数值符号与x相同,整数部分以浮点型表示。
[pow(x, y)] x**y 运算后的值。
[round(x [,n])] 返回浮点数x的四舍五入值,如给出n值,则代表舍入到小数点后的位数。
[sqrt(x)] 返回数字x的平方根,数字可以为负数,返回类型为实数,如math.sqrt(4)返回 2+0j

  • Python随机数函数
函数 返回值 ( 描述 )
[choice(seq)] 从序列的元素中随机挑选一个元素,比如random.choice(range(10)),从0到9中随机挑选一个整数。
[randrange ([start,] stop [,step])] 从指定范围内,按指定基数递增的集合中获取一个随机数,基数缺省值为1
[random()] 随机生成下一个实数,它在[0,1)范围内。
[seed([x])] 改变随机数生成器的种子seed。如果你不了解其原理,你不必特别去设定seed,Python会帮你选择seed。
[shuffle(lst)] 将序列的所有元素随机排序
[uniform(x, y)] 随机生成下一个实数,它在[x,y]范围内。

2.python中map()函数
map()是 Python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回。

#==============map函数使用===========
#按照首字母大写,后续字母小写的规则
#把一个list(包含若干不规范的英文名字)变成一个包含规范英文名字的list
#===================================
def format_name(s):
#    return s.capitalize()  # 把第一个字母转化为大写字母,其余小写
    return  s[0].upper()+s[1:].lower()    #两种方法都可实现   
print map(format_name, ['adam', 'LISA', 'barT'])

3.python中reduce()函数

#==============reduce函数使用===========
#输入:[2, 4, 5, 7, 12]
#输出:2*4*5*7*12的结果
#=====================================
def prod(x, y):
    return x*y

print reduce(prod, [2, 4, 5, 7, 12])
#reduce(f,list)对list的每个元素反复调用函数f,并返回最终结果值。
#还可以接收第3个可选参数,作为计算的初始值。

4.python中filter()函数
filter()函数接收一个函数f 和一个list,这个函数 f的作用是对每个元素进行判断,返回 TrueFalsefilter()根据判断结果自动过滤掉不符合条件的元素,返回由符合条件元素组成的新list

#===========filter函数的使用=============
#请利用filter()过滤出1~100中平方根是整数的数,
#即结果应该是:
#[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
#============================
import math
def is_sqr(x):
    return math.sqrt(x)%1 == 0
 #注意sqrt函数返回值是float型,所以不能使用字符串方法isdigit()
#直接用,isinstance(a,int)或者type(a)==int等方法都是false
print filter(is_sqr,range(1, 101))#注意range是包前不包后的

5.python中自定义排序函数
Python内置的 sorted()函数可对list进行排序:

>>>sorted([36, 5, 12, 9, 21])
[5, 9, 12, 21, 36]

sorted()接收两个参数,第一个是待比较的列表,第二个是一个比较函数来实现自定义排序。
比较函数的定义是,传入两个待比较的元素 x, y,如果 x 应该排在 y 的前面,返回 -1,如果 x 应该排在 y 的后面,返回 1。如果 x 和 y 相等,返回 0。

#==================题目========================
#对字符串排序时,有时候忽略大小写排序更符合习惯。
#请利用sorted()高阶函数,实现忽略大小写排序的算法。
#输入:['bob', 'about', 'Zoo', 'Credit']
#输出:['about', 'bob', 'Credit', 'Zoo']
#================实现一==========================
def cmp_ignore_case(s1, s2):
    return cmp(s1.lower(),s2.lower())
#cmp(x,y) 函数用于比较2个对象,如果 x < y 返回 -1, 如果 x == y 返回 0, 如果 x > y 返回 1。
print sorted(['bob', 'about', 'Zoo', 'Credit'], cmp_ignore_case)
#================实现二==========================
def cmp_ignore_case(s1, s2):
    if s1.upper()>s2.upper():
        return 1
    if s1.upper()<s2.upper():
        return -1
    return 0
print sorted(['bob', 'about', 'Zoo', 'Credit'], cmp_ignore_case)

6.python中返回函数
Python的函数不但可以返回int、str、list、dict等数据类型,还可以返回函数!

#========问题==============
#请编写一个函数calc_prod(lst)
#它接收一个list,返回一个函数
#返回函数可以计算参数的乘积。
#======================
def calc_prod(lst):
    def a():
        def prod(x, y):
            return x*y
        return reduce(prod,lst)
    return a

f = calc_prod([1, 2, 3, 4])
print f()

7.python中闭包

# 希望一次返回3个函数,分别计算1x1,2x2,3x3:
def count():
    fs = []
    for i in range(1, 4):
        def f():
             return i*i
        fs.append(f)
    return fs

#像这种内层函数引用了外层函数的变量(参数也算变量),然后返回内层函数的情况,称为闭包(Closure)
f1, f2, f3 = count()

你可能认为调用f1(),f2()和f3()结果应该是1,4,9,但实际结果全部都是 9
原因就是当count()函数返回了3个函数时,这3个函数所引用的变量 i 的值已经变成了3。由于f1、f2、f3并没有被调用,所以,此时他们并未计算 i*i,当 f1 被调用时:

>>> f1()
9     # 因为f1现在才计算i*i,但现在i的值已经变为3

因此,返回函数不要引用任何循环变量,或者后续会发生变化的变量。
要正确使用闭包,就要确保引用的局部变量在函数返回后不能变
8.python中的匿名函数

#以map()函数为例,计算 f(x)=x*x 时,除了定义一个f(x)的函数外,还可以直接传入匿名函数:
>>> map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9])
[1, 4, 9, 16, 25, 36, 49, 64, 81]
#关键字lambda 表示匿名函数,冒号前面的 x 表示函数参数。
#通过对比可以看出,匿名函数 lambda x: x * x 实际上就是:
def f(x):
    return x * x

9.python中的偏函数

#当一个函数有很多参数时,调用者就需要提供多个参数。
#如果减少参数个数,就可以简化调用者的负担。
#比如,int()提供base参数,默认值为10。如果传入base参数,就可以做 N 进制的转换:
>>> int('12345', base=8)
5349
>>> int('12345', 16)
74565
#假设要转换大量的二进制字符串,每次都传入int(x, base=2)非常麻烦,于是我们定义一个int2()的函数,默认把base=2传进去:
def int2(x, base=2):
    return int(x, base)
>>> int2('1000000')
64

functools.partial就是帮助我们创建一个偏函数的,不需要我们自己定义int2(),可以直接使用下面的代码创建一个新的函数int2:

>>> import functools
>>> int2 = functools.partial(int, base=2)
>>> int2('1000000')
64

functools.partial可以把一个参数多的函数变成一个参数少的新函数,少了的参数需要在创建时指定默认值。functools.partial第一个参数为要使用的函数(参数多的函数),第二个参数为原函数中需要减少的函数及其默认值。

#==============================================================
#在5小节中,我们在sorted函数中传入自定义排序函数就可以实现忽略大小写排序。
#请用functools.partial把这个复杂调用变成一个简单的函数:
#==============================================================
import functools
def cmp_ignore_case(s1, s2):
    if s1.upper()>s2.upper():
        return 1
    if s1.upper()<s2.upper():
        return -1
    return 0
sorted_ignore_case = functools.partial(sorted,cmp=cmp_ignore_case)
#注意这里的参数要指定默认值
print sorted_ignore_case(['bob', 'about', 'Zoo', 'Credit'])
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容