python语法(2)
map/reduce
map()函数接收两个参数,一个是函数,一个是Iterable,
map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。
1 | def f(x): |
reduce的用法。
reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,
这个函数必须接收两个参数:函数还有被作用的序列
reduce把结果继续和序列的下一个元素做累积计算,其效果就是:
1 | reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4) |
比方说对一个序列求和,就可以用reduce实现:
1 | from functools import reduce |
filter过滤函数
filter()接收一个函数和一个序列。
把传入的函数依次作用于每个元素,
然后根据返回值是True还是False决定保留还是丢弃该元素
1 | def not_empty(s): |
筛素数的方法,惰性筛选
1 | def primes(): |
迭代器后面的数根本没筛。
只是把“筛选规则”保存下来了。
等以后某个数字真正被生成时,再让它依次经过这些筛选规则。
例题,筛选回文数:
1 | def is_palindrome(n): |
1 | def int2list(n): |
sort()
sorted()函数接收一个key函数来实现自定义的排序,例如按绝对值大小排序:
1 | sorted([36, 5, -12, 9, -21], key=abs) |
key指定的函数将作用于list的每一个元素上,并根据key函数返回的结果进行排序。
1 | list = [36, 5, -12, 9, -21] |
并按照对应关系返回list相应的元素:
1 | result sort = [5, 9, -12, -21, 36] |
要进行反向排序,不必改动key函数,可以传入第三个参数reverse=True
返回函数与闭包
注意到返回的函数在其定义内部引用了局部变量args,所以,当一个函数返回了一个函数后,其内部的局部变量还被新函数引用。
另一个需要注意的问题是,返回的函数并没有立刻执行,而是直到调用了f()才执行。
返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
如果一定要引用循环变量,
方法是再创建一个函数,用该函数的参数绑定循环变量当前的值,
1 | def count(): |
nonlocal
内层函数引用外层函数局部变量
只读则调用正常
赋值改写则会报错,要加nonlocal x声明
使用闭包时,对外层变量赋值前,需要先使用nonlocal声明该变量不是当前函数的局部变量。
匿名函数(lambda)
1 | def f(x): |
匿名函数也可以作为返回值返回
装饰器Decorator
1 | import functools |
三层嵌套,针对装饰器带参数的
1 | import functools |
1 |
|
经过decorator装饰之后的函数,它们的__name__已经从原来的'now'变成了'wrapper'
1 | now.__name__ |
所以要加@functools.wraps(func)
偏函数
就是制作了一个有其他默认参数的函数
1 | int2 = functools.partial(int, base=2)#默认转二进制 |
创建偏函数时,实际上可以接收函数对象、*args和**kw这3个参数
如果不些命名参数则就是位置参数
当传入:
1 | max2 = functools.partial(max, 10) |
实际上会把10作为*args的一部分自动加到左边,也就是:
1 | max2(5, 6, 7) |
相当于:
1 | args = (10, 5, 6, 7) |
结果为10。
模块
和java差不多,每一个包目录下面都会有一个__init__.py的文件
要注意:
- 模块名要遵循Python变量命名规范,不要使用中文、特殊字符;
- 模块名不要和系统模块名冲突,最好先查看系统是否已存在该模块,检查方法是在Python交互环境执行
import abc,若成功则说明系统存在此模块。
作用域
类似__xxx__这样的变量是特殊变量,比如上面的__author__,__name__
类似_xxx和__xxx这样的函数或变量就是非公开的(private),不应该被直接引用,比如_abc,__abc等;
外部不需要引用的函数全部定义成private,只有外部需要引用的函数才定义为public。