python函数廖雪峰_python高阶函数学习笔记

#python进阶学习笔记1(廖雪峰课程)

##高阶函数

python和Js很像,支持将函数作为变量输入到参数的参数里面去,此时将函数作为参数的函数称之为高阶函数

变量也是可以指向函数的,例如:1

2

3fun=abs()

fun(-10)

一般存在一下几个常用的高阶函数,将list和function作为参数输入处理:

map函数的例子1

2

3

4

5def (x):

return x*x

print map(f,[range(1,10)])

#输出的结果是[x for x in range(1,82) if math.sqrt(x) in range(1,10)]

reduce函数1

2

3

4def (x,y):

return x+y

reduce(f,range(1,10)[::2])

该函数输出的结果是:1

2

3

4

5先计算头两个元素:f(1, 3),结果为4;

再把结果和第3个元素计算:f(4, 5),结果为9;

再把结果和第4个元素计算:f(9, 7),结果为16;

再把结果和第5个元素计算:f(16, 9),结果为25;

由于没有更多的元素了,计算结束,返回结果25。

reduce函数还可以指定计算的初始值:1

2reduce(f,range(1,10)[::2],100)

#输出的结果:125

filter()函数:filter()根据判断结果自动过滤掉不符合条件的元素,返回由符合条件元素组成的新list。1

2

3

4

5def is_odd(x):

return x %2 ==1

filter(is_odd,[1,4,6,7,9,12,17])

#输出结果 [1,7,9,17]

利用filter(),可以完成很多有用的功能,例如,删除 None 或者空字符串:1

2

3

4

5

6

7

8

9

10

11

12def is_not_empty(s):

return s and len(s.strip())>0

filter(is_not_empty, ['test', None, '', 'str', ' ', 'END'])

#输出结果 :['test', 'str', 'END']

#注意: s.strip(rm) 删除 s 字符串中开头、结尾处的 rm 序列的字符。

#当rm为空时,默认删除空白符(包括'n', 'r', 't', ' '),如下:

a = ' 123'

a.strip()

#结果是 '123'

自定义排序函数

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

因此,如果我们要实现倒序排序,只需要编写一个reversed_cmp函数:1

2

3

4

5

6

7

8

9

10def reversed_cmp(x, y):

if x > y:

return -1

if x < y:

return 1

return 0

# 实现倒序排序

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

#输出结果:[36, 21, 12, 9, 5]

python中的函数作为变量看待

python最骚的就是和JS一样将函数作为变量看待,一个函数的返回值是可以返回一个函数!!!,因为python将函数作为变量看待

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

例如,定义一个函数 f(),我们让它返回一个函数 g,可以这样写:1

2

3

4

5

6

7

8def ():

print 'call f()'

#定义一个g函数

def g():

print 'call g()'

#函数g作为返回,注意返回的是函数名!!!

return g

执行的结果:1

2

3

4

5

6>>> x = f() # 调用f()

call f()...

>>> x # 变量x是f()返回的函数:

>>> x() # x指向函数,因此可以调用

call g()... # 调用x()就是执行g()函数定义的代码

注意返回函数的时候是返回函数名,不是调用函数1

2

3

4

5

6

7def myabs():

return abs

#返回的是函数名

def myabs1(x):

return abs(x)

#返回的是值!!!

python中的闭包操作

和Js一模一样,在一个函数里面定义另一个函数,在这个函数里面存在定义函数的外部变量封装起来1

2

3

4

5def ():

a='local'

def g():

print a

return g

这里看起来函数g中的变量a是外界看不到的变量,廖雪峰老师的进阶课程中对闭包的解释:

例子:1

2

3

4def calc_sum(lst):

def lazy_sum():

return sum(lst)

return lazy_sum

注意: 发现没法把 lazy_sum 移到 calc_sum 的外部,因为它引用了 calc_sum 的参数 lst。

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

闭包的特点是返回的函数还引用了外层函数的局部变量,所以,要正确使用闭包,就要确保引用的局部变量在函数返回后不能变。

一个闭包错误的例子:1

2

3

4

5

6

7

8

9

10# 希望一次返回3个函数,分别计算1x1,2x2,3x3:

def count():

fs = []

for i in range(1, 4):

def ():

return i*i

fs.append(f)

return fs

f1, f2, f3 = count()

你可能认为调用f1(),f2()和f3()结果应该是1,4,9,但实际结果全部都是 9(请自己动手验证)。

原因就是当count()函数返回了3个函数时,这3个函数所引用的变量 i 的值已经变成了3。由于f1、f2、f3并没有被调用,所以,此时他们并未计算 i*i,当 f1 被调用时:1

2>>> f1()

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

因此,返回函数不要引用任何循环变量,或者后续会发生变化的变量。

我的理解

python在执行对应的程序的时候才去读取对应的i值,此时的for已经结束,因此i一直都是3,修改代码:1

2

3

4

5

6

7

8

9

10

11def count():

fs=[]

for i in range(1,4):

def f(x=i):

return x*x

fs.append(f)

return fs

f1,f2,f3=count()

print f1(),f2(),f3()

#输出理想的结果 1,4,9

Python中的闭包其实还有一个问题,外层函数的变量和里层函数的变量重名,但是这个变量不是总的函数的外部变量,这就会出bug:1

2

3

4

5

6

7

8

9

10def fun1():

count=0

def func():

count+=1

print 'Now count is',count

return func

test=fun1()

test()

#直接会报错哦

解决方案加入关键词 nonlocal(python 3支持)1

2

3

4

5

6

7

8

9

10

11def fun1():

count=0

def func():

nonlocal count+=1

print 'Now count is',count

return func

test=fun1()

test()

test()

test()

python中的匿名函数

套路和JS很像直接在参数传入的过程中定义一个简单的函数

但是JS是有关键字function的,而python中的关键词是lambda!!!

简单示例函数:1

2map(lambda x:x*x,range(1,10))

#输出结果[1,4,9,16,25,36,49,64,84]

匿名函数的实体定义类似:1

2def f(x):

return x*x

关键字lambda 表示匿名函数,冒号前面的 x 表示函数参数。

匿名函数有个限制,就是只能有一个表达式,不写return,返回值就是该表达式的结果。

这也是python比JS的不足,JS的匿名函数没有那么多限制就是直接定义,但是python的灵活就在于函数对象的使用,例如:1

2sorted([1, 3, 9, 5, 0], lambda x,y: -cmp(x,y))

#结果:[9, 5, 3, 1, 0]

返回函数的时候,也可以返回匿名函数:1

2

3

4

5>>> myabs = lambda x: -x if x < 0 else x

>>> myabs(-1)

1

>>> myabs(1)

1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值