说明
python的进阶用法之一就是生成器、迭代器的用法,使用生成迭代可以极大地减少代码的行数,使得代码简明易读。
列表生成式
range(1,100,5) #第一个参数表示开始位,第二个参数表示结束位(不含),第三个参数表示步长,就是每5个数返回一次。
a = [i for i in range(1,10)] #列表生成式表示返回i的值,并且返回9次,每次返回的是i的值。
a = [2 for i in range(1,10)] #这里表示返回2,并且返回9次,但是每次的值都是2。
a = [i for i in range10 if i%2==0] #只返回偶数。
a = [(i,j) for i in range(5) for j in range(5)] #二维元组的遍历。
生成器
a = (i for i in range(1,10)) #与list的区别为[]和()
next(a),a.__next__() #生成器的取值方式只能使用next的方法。
# fobi
def num():
a,b = 0,1
for i in range(10):
yield b # yield和return返回类似,只不过yield后会继续执行,且函数返回值为生成器。
a,b = b,a+b
a = num()
for n in a: # 使用for进行迭代
print(n)
注意:生成器占用内存小,在使用的时候取值,降低CPU和内存空间,提高效率。
迭代器
迭代器是所有生成器和生成列表的基类。
# '',[],(),{},{:} 都是可迭代的对象,迭代器的子类
a = (x for i in range(100)) #[]为生成列表,()为生成器
from collections.abc import Iterable #python33之后需要用collections.abc而非collections
print(isinstance('abc',Iterable)) # True
a = [1,2,3,4,5]
b = iter(a) # 列表转化为迭代器
print(next(b)) # 1
注意:生成器是可迭代对象,迭代器不一定是生成器。并且迭代器无法回取,只能向前取值。
注意:一个对象具有 iter 方法的才能称为可迭代对象,使用yield生成的迭代器函数,也有iter方法。凡是没有iter方法的对象不是可迭代对象,凡是没有__next__()方法的不是是生成器。(这里的方法都是魔法方法,是内置方法,可以使用dir()查看)
itertools系统库
itertools集成了大部分的迭代函数,可以方便地求前缀和,前缀积等。
accumulate函数
import operator
from itertools import accumulate
x = accumulate(range(1, 10), operator.add) # 前缀和, 可以改为operator.mul求前缀积
print(list(x))
x = accumulate(range(1,10), max)
print(list(x))
# [1, 3, 6, 10, 15, 21, 28, 36, 45]
# [1, 2, 3, 4, 5, 6, 7, 8, 9]
排列组合
permutations会生成所有全排列
from itertools import permutations
x = permutations("ACB")
print(list(x))
# [('A', 'C', 'B'), ('A', 'B', 'C'), ('C', 'A', 'B'), ('C', 'B', 'A'), ('B', 'A', 'C'), ('B', 'C', 'A')]
combinations会生成所有组合
from itertools import combinations
x = combinations('ABCD', 2)
print(list(x))
# [('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'C'), ('B', 'D'), ('C', 'D')]