一、函数式编程之高阶函数
print(abs(-10))
结果:10
<built-in function abs> —abs(-10)是函数调用 abs是函数本身
获得函数调用的结果 可以把结果赋值给变量
x=abs(-13)
print(x)
结果:13
把函数本身赋值给变量
x=abs
print(x)
<built-in function abs>—-结论:函数本身可以赋值给变量 变量可以指向函数
通过该变量来调用这个函数
x=abs
print(x(-12))
结论:变量x已经指向了abs函数本身 直接调用abs()函数和调用变量x()完全相同
二、函数名 —函数名也是变量
1.函数名就是指向函数的变量 把abs看成变量 它指向一个可以计算绝对值的函数
2.abs函数定义在import builtins模块当中
三、函数可以指向变量 (高阶函数)
1.举例一个简单的高阶函数
def add(x,y,a):
return a(x)+a(y)
print(add(1,-2,abs))
结果:3
四、高阶函数之map/reduce
1.Python內建的函数
2.代码实现:
def f(x):
return x*x
r=map(f,[1,2,3,4,5])
print(list(r))
3.不用map()函数 直接写一个循环来进行计算
def f(x):
return x*x
L=[]
for n in [1,2,3,4,5]:
L.append(f(n))
print(L)
4.reduce 求一个序列的和
from functools import reduce
def add(x,y):
return x+y
print(reduce(add,[1,3,5,7,9]))
运行结果:25
5.reduce內建函数
from functools import reduce
def fn(x,y):
return x*10+y
print(reduce(fn,[1,3,5,7,9]))
五、高阶函数之filter
1.python內建filter()函数用于过滤序列
根据返回值的true和false 决定是否保留或丢弃该元素
def is_odd(n):
return n%2 == 1
print(list(filter(is_odd,[1,3,5,8,19])))
结果:[1, 3, 5, 19]
2.把序列的空字符串删除
def no_empty(s):
return s and s.strip()
print(list(filter(no_empty,['A','','B',None,'C',''])))
3.用filter求素数
def _odd_iter():
n = 1
while True:
n = n+2
yield n
def _not_divisible(n):
return lambda x:x%n>0
def primas():
yield 2
it =_odd_iter()
while True:
n = next(it)
yield n
it = filter(_not_divisible(n),it)
for n in primas():
if n <1000:
print(n)
else:
break
六、高阶函数之sorted
1.排序算法 sorted排序
print(sorted([36,12,3,6,91]))
2.按绝对值排序 接受一个key函数实现自定义排序
print(sorted([-12,4,7,19,-1],key=abs))
3.字典串排序 传入key值可以忽略字母的大小写进行排序
print(sorted(['bob','about','zoo','credit'],key=str.lower))
4.倒叙排序 加上reverse=True
print(sorted(['bob','about','zoo','credit'],key=str.lower,reverse=True))
七、返回函数
1.返回函数:函数作为返回值
def lazy_num(*args): #在lazy_num中定义了函数sum 内部函数sum可以引用外部函数
def sum(): #lazy_num的参数和局部变量
ax = 0
for n in args:
ax=ax+n
return ax
return sum
p1=lazy_num(1,2,7,12,13)
p2=lazy_num(87,34,1,41)
print(p1())
print(p2())
2.什么叫闭包?
就是在一个函数里面定义了一个新的函数,这个新的内部函数可以引用外部函数的参数和局部变量,当外部函数返回内部函数的时候,相关的参数和变量都保存在返回的参数中这种就称为闭包。。。
3.接上面 返回的函数在其定义内部引用了局部变量args 当一个函数返回一个函数后 其内部的局部变量被新函数引用,而且要用p1()调用 直接用p1是调用不了的
八、匿名函数
1.以map()函数为例,计算f(x)=x2时,除了定义一个f(x)的函数外,还可以直接传入匿名函数:
list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
2.匿名函数lambda x: x * x实际上就是:
def f(x):
return x * x
3. 关键字lambda表示匿名函数,冒号前面的x表示函数参数。匿名函数只能有一个表达式 不用写return 返回值就是该表达式的结果
4.匿名函数式一个函数对象,可以把匿名函数赋值给一个变量 再利用变量来调用该函数
>>> f = lambda x: x * x
>>> f
<function <lambda> at 0x101c6ef28>
>>> f(5)
25
5.也可以把匿名函数作为返回值返回
def build(x, y):
return lambda: x * x + y * y
九、装饰器
1.装饰器:函数也是一个对象 且函数对象可以被赋值给变量 所以变量也能调用该函数
>>> def now():
... print('2015-3-25')
...
>>> f = now
>>> f()
2015-3-25
2.函数对象有一个__name__属性,可以拿到函数的名字
>>> now.__name__
'now'
>>> f.__name__
'now'
3.装饰器(Decorator):假设要增强now()函数的功能,又不希望修改now()函数的定义 这种在代码运行期间动态增加功能的方式称为:装饰器(Decorator)
代码如下:
def log(func):
def wrapper(*args,**kw):
print('call %s:' % func.__name__)
return func(*args,**kw)
return wrapper
@log
def now():
print('2018-05-08')
now()
十、偏函数
1.通过设定参数的默认值,降低函数调用的难度
int()函数可以把字符串转换为整数
>>> int('12345') ---int()函数默认按十进制转换
12345
print(int('12345',base=8)) ---传入base参数 可以做2-36进制转换
2.转换大量的二进制字符串
def int2(x,base=2):
return int(x,base)
print(int2('1000000'))
3.创建偏函数 实际上固定了int()函数的关键字参数base
import functools
int2=functools.partial(int,base=2)
print(int2('10101'))
4.args=(10,5,6,7,)
print(max(*args))