求学者

Python 高级特性(廖雪峰版)

接上一版

Python 高级特性

切片 Slice

切片 主要是对 list&tuple 索引进行操作

迭代 Iteration

使用for ... in 进行迭代操作

Iterable:可迭代对象

isinstance(str, Iterable): 是否为可迭代对象
enumerate(list): 将 list 转化为索引-元素对

列表生产式 List Comprehensions

eg:生成10以内仅偶数的平方集合
[x*x for x in range(1,11) if x%2==0]

生产器 generator

gererator: 一边循环一边计算的机制,通过循环推算后续的元素,保存算法
定义 generator 使用 yield 输出关键字。

1
2
3
4
5
6
### 生成器 作业 杨辉三角
def triangles():
L=[1]
while True:
yield L
L = [1]+[L[x]+L[x+1] for x in range(len(L)-1)] +[1]

迭代器 Iterator

迭代器: 可以被next()函数调用并不断返回下一个值的对象

isinstance(str, Iterator): 是否为迭代器
iter(str): 将str list dict转化为迭代器

Python 函数式编程

函数式编程 Functional Programming

函数式编程就是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量,因此,任意一个函数,只要输入是确定的,输出就是确定的,这种纯函数我们称之为没有副作用。

函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数!

Python 对函数式编程提供部分支持。

高阶函数 Higher-order function

  • 变量可以指向函数
  • 函数名是指向函数的变量

既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数

map/reduce 函数

map(函数, Iterable): 两个参数,第一个为函数,第二个为可迭代对象,将函数依次作用到 Iterable 的每个元素,将结果作为 Iterator 返回。
reduce(函数, Iterable): 将函数的结果和 iterable 的下一元素做累积计算,函数必须接受两个参。

1
2
3
4
5
6
7
8
9
10
11
# eg:str to int
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 char2num(s):
return DIGITS[s]
return reduce(fn, map(char2num, s))

filter 函数

filter 用于过滤序列

filter(函数, iterable): 将函数依次作用于每个元素,根据返回值是Ture还是false决定保留还是丢弃该元素。返回结果Iterator

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 练习 filter求素数
# 从3开始的奇数序列
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_tier() # 初始序列
while True:
n = next(it) # 返回序列第一个数
yield n
it = filter(_not_divisible(n), it)

sorted 排序

sorted(list, key=函数, reverse=True): 接收一个key函数,对list进行排序,reverse确定是否反向排序

返回函数

高阶函数可以接受函数作为参数,也可以把函数作为结果返回

1
2
3
4
5
6
7
8
# eg 返回求和的函数
def lazy_sum(*args):
def sum():
ax = 0
for x in args:
ax = ax + n
return ax
return sum

闭包问题

注意:返回的函数中引用了局部变量args,当返回一个函数后,其内部的局部变量还被新的函数引用。

!返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。如果一定要引用,在创建一个函数,将变量作为参数绑定当前值

1.内部函数一般无法修改外部函数的参数
2.想要修改需要声明 nonlocal
3.内部函数可以修改外部list中的元素

匿名函数

关键字lambda标识匿名函数,:之前为参数,之后为返回结果

装饰器(Decorator)

装饰器 在代码运行期间动态增强功能的方式,本质上是一个装饰器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# eg 定义一个能打印日志的decorator
def log(text):
def decorator(func):
# 防止name改变
@functools.wraps(func)
def wrapper(*args, **kw):
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)
return wrapper
return decorator
# 用法
@log('execute') def func()...
# 相当于
func = log('execute')func