【Python】函数式编程&读写文件
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了【Python】函数式编程&读写文件,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含6135字,纯文字阅读大概需要9分钟。
内容图文
![【Python】函数式编程&读写文件](/upload/InfoBanner/zyjiaocheng/623/2657c27ea301416c8b88fa6fa00cf55a.jpg)
九、Python 函数式编程
1、什么是函数式编程
1.1 函数:function,逻辑功能的单位;函数式:functional,一种编程范式。函数不等于函数式。
1.2 特点:允许有变量;函数可以作为变量;函数可以返回函数;支持匿名函数
2、把函数作为参数
##计算平方根 import math def add(x, y, f): return f(x) + f(y) print(add(25, 9, math.sqrt)) #==>8.0
3、map()函数
map()是 Python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把函数 f依次作用在list的每个元素上,map()函数会返回一个迭代器,可以依次迭代得到原来list的元素被函数f处理后的结果。
def f(x): return x*x for item in map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9]): print(item) #==>[1, 4, 9, 10, 25, 36, 49, 64, 81]
4、reduce()函数
reduce()函数接收的参数和 map() 类似,一个函数 f,一个list,但行为和 map()不同,reduce()传入的函数 f 必须接收两个参数,reduce()对list的每个元素反复调用函数f,并返回最终结果值。在python3中,reduce()函数被收录到functools包内,需要引入functools才可以使用。
from functools import reduce def f(x, y): return x + y print(reduce(f, [1,3,5,7,9])) # ==> 25 #还可以接收第3个可选参数,作为计算的初始值 print(reduce(f, [1, 3, 5, 7, 9], 100)) # ==> 125
5、filter()函数
filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回 True或 False,filter()根据判断结果自动过滤掉不符合条件的元素,并返回一个迭代器,可以迭代出所有符合条件的元素。
#删除 None 或者空字符串 def is_not_empty(s): return s and len(s.strip()) > 0 for item in filter(is_not_empty, ['test', None, '', 'str', ' ', 'END']): print(item) #==>test, str, END #注意: s.strip()会默认删除空白字符(包括'\n', '\r', '\t', ' ') s = ' 123' s.strip() # ==> 123 s= '\t\t123\r\n' s.strip() # ==> 123 #过滤出1~100中平方根是整数的数 import math def is_sqrt(x): r = int(math.sqrt(x)) return r * r == x for item in filter(is_sqrt, range(1, 101)): print(item) #==>1, 4, 9, 16, 25, 36, 49, 64, 81, 100
6、自定义排序函数
6.1 内置的 sorted()函数可对list进行排序,默认是由小到大排序列表的元素
sorted([36, 5, 12, 9, 21]) #==>[5, 9, 12, 21, 36]
6.2 list的每一个元素又是一个容器时,则会以第一个元素来排序,sorted接受key参数,用来指定排序的字段,key的值是一个函数,接受待排序列表的元素作为参数,并返回对应需要排序的字段
score = [('Alice', 72), ('Candy', 90), ('Bob', 62)] sorted(score) #==>[('Alice', 72), ('Bob', 62), ('Candy', 90)] #按照成绩来进行排序 def k(item): return item[1] # ==> 按成绩排序,成绩是第二个字段 sorted(score, key=k) #==>[('Bob', 62), ('Alice', 72), ('Candy', 90)] #倒序指定 sorted(score, key=k, reverse=True) #==>[('Candy', 90), ('Alice', 72), ('Bob', 62)]
7、返回函数
7.1 在函数内部,是可以定义子函数的。
7.2 返回函数和返回函数值的语句是非常类似的,返回函数时,不能带小括号,而返回函数值时,则需要带上小括号以调用函数。
##编写一个函数calc_prod(list_),它接收一个list,返回一个函数,返回函数可以计算参数的乘积。 from functools import reduce def calc_prod(list_): def lazy_prod(): def f(x, y): return x * y return reduce(f, list_, 1) return lazy_prod f = calc_prod([1, 2, 3, 4]) print(f()) #==>24
8、闭包
8.1 像这种内层函数引用了外层函数的变量(参数也算变量),然后返回内层函数的情况,称为闭包(Closure)。
8.2 闭包的特点是返回的函数还引用了外层函数的局部变量,所以,要正确使用闭包,就要确保引用的局部变量在函数返回后不能变。
8.3 返回函数不要引用任何循环变量,或者后续会发生变化的变量。
#返回闭包不能引用循环变量,请改写count()函数,让它正确返回能计算1x1、2x2、3x3的函数 def count(): fs = [] for i in range(1, 4): def f(j): def g(): return j*j return g r = f(i) fs.append(r) return fs f1, f2, f3 = count() print(f1(), f2(), f3()) #==>(1, 4, 9)
9、匿名函数
匿名函数使用lambda定义:lambda x: x * x,就可以完成原来显式定义的f(x)函数的功能,冒号前面的x表示匿名函数的参数,后面的是一个表达式,匿名函数有个限制,就是只能有一个表达式,不写return,返回值就是该表达式的结果。
result = [item for item in map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9])] print(result) # ==> [1, 4, 9, 16, 25, 36, 49, 64, 81]
10、编写无参数的decorator
10.1 decorator 本质上就是一个高阶函数,它接收一个函数作为参数,然后,返回一个新函数。
10.2 decorator 用Python提供的 @ 语法(装饰器),这样可以避免手动编写 f = decorate(f) 这样的代码
#@log的定义 def log(f): def fn(x): print('call ' + f.__name__ + '()...') return f(x) return fn #阶乘函数 @log def factorial(n): return reduce(lambda x,y: x*y, range(1, n+1)) print(factorial(10)) #==>call factorial()... #==>3628800
10.3 以上只能传入一个参数,因为@log是写死了只含一个参数的,要是保证任意个数,应该使用args和*kwargs
def log(f): def fn(*args, **kwargs): print('call ' + f.__name__ + '()...') return f(*args, **kwargs) return fn
10.4 请编写一个@performance,它可以打印出函数调用的时间。
###计算函数调用的时间可以记录调用前后的当前时间戳,然后计算两个时间戳的差。 import time def performance(f): def fn(*args, **kw): t1 = time.time() r = f(*args, **kw) t2 = time.time() print('call %s() in %fs' % (f.__name__, (t2 - t1))) return r return fn @performance def factorial(n): return reduce(lambda x,y: x*y, range(1, n+1)) print(factorial(10)) #==>call factorial() in 0.005034s #==>3628800
11、编写有参数的decorator
11.1 发现对于被装饰的函数,log打印的语句是不能变的(除了函数名)。
11.2 如果有的函数非常重要,希望打印出'[INFO] call xxx()...'。有的函数不太重要,希望打印出'[DEBUG] call xxx()...'。这时,log函数本身就需要传入'INFO'或'DEBUG'这样的参数,类似这样:
@log('DEBUG') def my_func(): pass ##把上面的定义翻译成高阶函数的调用 my_func = log('DEBUG')(my_func) #其实也就是下面这样的内容 log_decorator = log('DEBUG') my_func = log_decorator(my_func) #也可以写作下面这样 log_decorator = log('DEBUG') @log_decorator def my_func(): pass
综上其实就是:
def log(prefix): def log_decorator(f): def wrapper(*args, **kw): print('[{}] {}()...'.format(prefix, f.__name__)) return f(*args, **kw) return wrapper return log_decorator @log('DEBUG') def test(): pass test() #==>[DEBUG] test()...
12、偏函数
12.1 偏函数指的就是“创建一个调用另外一个部分参数或变量已经预置的函数”的函数的用法。一个栗子:int()函数的base参数,没有指定的时候,默认是以十进制工作的,当指定base=2的时候,int2实际上就变成了部分参数(base)已经预置了的偏函数。
12.2 functools.partial就是帮助我们创建一个偏函数的,不需要我们自己定义int2(),可以直接使用下面的代码创建一个新的函数int2:
>>> import functools >>> int2 = functools.partial(int, base=2) >>> int2('1000000') 64 >>> int2('1010101') 85
12.3 functools.partial可以把一个参数多的函数变成一个参数少的新函数,少的参数需要在创建时指定默认值
内容总结
以上是互联网集市为您收集整理的【Python】函数式编程&读写文件全部内容,希望文章能够帮你解决【Python】函数式编程&读写文件所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。