函数式编程
高阶函数
传入函数
既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数称为高阶函数
def add(x, y, f):
return f(x) + f(y)
print(add(-3,5,abs))
map/reduce
map(func, *iterables) --> map object
Make an iterator that computes the function using arguments from each of the iterables. Stops when the shortest iterable is exhausted.
map()接收两个参数,一个是函数,一个是Iterbale,map将传入的函数依次作用于序列的每个元素,并把结果作为新的Iterator返回
def f(x):
return x * x
r = map(f, [1,2,3,4,5])
list(r)
把list所有数字转为字符串
list(map(str, [1,2,3,4,5]))
reduce
reduce(function, sequence[, initial]) -> value
Apply a function of two arguments cumulatively to the items of a sequence,from left to right, so as to reduce the sequence to a single value.For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates ((((1+2)+3)+4)+5). If initial is present, it is placed before the items of the sequence in the calculation, and serves as a default when the sequence is empty.
reduce()接收两个参数,函数和序列,其中函数也要有两个参数,reduce把结果和序列剩下的部分依次进行计算,效果就是
reduce(f,[x1,x2,x3,x4,x5])=f(f(f(f(x1,x2),x3),x4),x5)
如求和
from functools import reduce
def add(x,y):
return x+y
reduce(add,[1,2,3,4,5])
把序列变换成整数
from functools import reduce
def fn(x,y):
return x * 10 + y
reduce(fn,[1,2,3,4,5])
把str转换成int
from functools import reduce
def fn(x,y):
return x * 10 + y
def chr2num(s):
digits = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
return digits[s]
reduce(fn, map(chr2num,'12345'))
整理成str2int的函数
from functools import reduce
DIGITS = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
def str2int(s):
def fn(x, y):
return x * 10 + y
def chr2num(s):
return DIGITS[s]
return reduce(fn, map(chr2num, s))
用lambda函数精简
from functools import reduce
DIGITS = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
def chr2num(s):
return DIGITS[s]
def str2int(s):
return reduce(lambda x, y: x * 10 + y, map(chr2num, s))
filter
python内建的filter()函数用于筛选序列,接收一个函数和序列作为参数,与map()不同的是,把传入的函数依次作用于元素,并根据返回值是True还是False来确定是保留还是去除该元素
如在一个list中,删掉偶数,只保留奇数
def is_odd(n):
return n%2==1
list(filter(is_odd, [1,2,3,4,5]))
把一个序列中的空字符串删掉
def not_empty(s):
return s and s.strip()
list(filter(not_empty, ['a','','b',None,'c',' ']))
用filter求素数
计算素数的一个方法是埃氏筛法,首先构造从2开始的所有自然数序列,取序列的第一个数2,它是素数,然后用2把2的倍数筛掉;取序列的第一个数3,它是素数,然后用3把序列的3的倍数筛掉;取新序列的第一个数5,然后用5把序列的5的倍数筛掉;不断筛下去,就可以得到所有的素数
def _odd_iter():
n = 1
while True:
n = n + 2
yield n
def _not_divisible(n):
return lambda x: x % n > 0
def primes():
yield 2
it = _odd_iter()
while True:
n = next(it)
yield n
it = filter(_not_divisible(n), it)
for n in primes():
if n < 1000:
print(n)
else:
break
sorted
sorted([36,5,-12,9,-21], key=abs)
key指定的函数将作用于list的每一个元素上,并根据key函数返回的结果进行排序
sorted(['bob','about','Zoo','Credit'],key=str.lower)
对列表按名字排序
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
def by_name(t):
for s in t:
return s.lower()
L2 = sorted(L, key=by_name)
print(L2)
按成绩从高到低排序
def by_score(t):
for n in t:
if isinstance(n, str):
pass
else:
return n
L3 = sorted(L, key=by_score, reverse=True)
print(L3)
返回函数
函数作为返回值
def calc_sum(*args):
ax = 0
for n in args:
ax += n
return ax
def lazy_sum(*args):
def sum():
ax = 0
for n in args:
ax += n
return ax
return sum
当调用lazy_sum(),返回的是求和函数
f = lazy_sum(1,2,3,4,5)
调用函数f(),才得到求和结果
f()
当调用lazy_sum(),即使每次传入参数一样,也会返回新的函数
闭包
def count():
fs = []
for i in range(1,4):
def f():
return i*i
fs.append(f)
return fs
f1, f2, f3 = count()
执行
f1()
f2()
f3()
得到相同结果9,原因在于返回的函数引用了变量i,但它并非立即执行,等到3个函数都返回时,i已经变成3,因此最终结果为9
返回闭包时牢记,返回函数不要引用任何循环变量,或许后续会发生变化的变量
如果一定要引用循环变量,方法是再创建一个函数,用该函数的参数绑定循环变量的当前值
def count():
def f(j):
def g():
return j*j
return g
fs = []
for i in range(1,4):
fs.append(f(i))
return fs
f1, f2, f3 = count()
f1()#1
f2()#4
f3()#9
利用闭包返回一个计数器函数,每次调用返回递增整数
#列表
def createCounter():
count = []
def counter():
count[0] = count[0] + 1
return count[0]
return counter
#生成器
def createCounter():
g = (i for i in range(1, 1000))
def counter():
return next(g)
return counter
#用nonlocal,LEGB原则,nonlocal是python3引入的,只能用于嵌套函数中,在嵌套函数中使用nonlocal声明变量,可以修改外层函数中的变量
def createCounter():
n = 0
def counter():
nonlocal n
n = n + 1
return n
return counter
匿名函数
匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数,也可以将匿名函数作为返回值返回
装饰器
待补充
偏函数
待补充

浙公网安备 33010602011771号