1.列表生成式
现在有一个列表lis[0,1,2,3,4,5,6,7,8,9],现需要将里面每个元素+1,可以用过遍历、高阶函数map()都能实现,其实还有一个更简单的方法:列表生成式。
列表遍历
1 lis = [0,1,2,3,4,5,6,7,8,9] 2 b = [] 3 for i in lis: 4 b.append(i+1) 5 print(b) 6 结果: 7 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
高阶函数map()
1 lis = [0,1,2,3,4,5,6,7,8,9] 2 def fun(x): 3 return x +1 4 ret = map(fun,lis) 5 print(list(ret)) 6 结果: 7 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
列表生成式
1 lis = [0,1,2,3,4,5,6,7,8,9] 2 b = [i + 1 for i in lis] 3 print(b) 4 结果: 5 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
上述方法都是建立在生成一个列表的基础上,当列表的元素贼多时,都加载到内存中会占用很多内存,而上述问题中后面的元素都是可以通过计算推导出来的。于是python中定义了生成器,即一边循环一边计算的机制称之为生成器。
2.生成器
生成器一次只能生成一个值,消耗的内存大大减少。
创建生成器有很多种方法,最简单的一种就是将列表生成式中"[]"改成"()"即可。
1 lis = [0,1,2,3,4,5,6,7,8,9] 2 b = (i + 1 for i in lis) 3 print(b) 4 结果: 5 <generator object <genexpr> at 0x000001E69D7DC938>
列表生成式打印出来的是一个列表,而生成器打印出来的是:<generator object <genexpr> at 0x000001E69D7DC938>。
若想获取生成器的值,需通过next()获取。
1 lis = [0,1,2,3,4,5,6,7,8,9] 2 b = (i + 1 for i in lis) 3 print(next(b)) 4 结果: 5 1
此时每调用一次next()就会返回一个生成器的值,直到没有更多的元素时,报出StopIteration的错误。
但是吧,如果一直重复用next()调用太low,可以用for循环来迭代,而且还不怕报StopIteration的错误。
1 lis = [0,1,2,3,4,5,6,7,8,9] 2 b = (i + 1 for i in lis) 3 for i in b: 4 print(i) 5 结果: 6 1 7 2 8 3 9 4 10 5 11 6 12 7 13 8 14 9 15 10
生成器是一个特殊的函数,用关键字yield控制,一次只返回一个值,顺序同样从上往下依次执行,但是当遇到yield时返回一个值,且暂停执行,保存当前状态,当遇到另一个__next__()时从此处继续执行。
1 def fun(): 2 yield 1 3 yield 2 4 yield 3 5 f = fun() 6 print(f.__next__()) 7 结果: 8 1
也可以用for循环迭代。
1 def fun(): 2 yield 1 3 yield 2 4 yield 3 5 for i in fun(): 6 print(i) 7 结果: 8 1 9 2 10 3
3.可迭代对象
可以直接用于for循环的对象统称为可迭代对象。
集合数据类型:list、tuple、str、set以及生成器都时可迭代对象。
判断是否时可迭代对象:
1 from collections import Iterable 2 lis = [1,2,3] 3 print(isinstance(lis,Iterable)) 4 结果: 5 True
4.迭代器
可以被next()函数调用,并不断返回下一个值的对象称迭代器。
迭代器的对象表示的是一个数据流,迭代器可以被next()函数调用返回下一个数据,知道没有数据时,抛出异常错误。
迭代器时惰性的,可以认为是一个有序序列,但是不知道长度。
生成器是一种特殊的迭代器。
list、dict、str是可迭代对象,但不是迭代器
1 from collections import Iterable 2 from collections import Iterator 3 lis = [1,2,3] 4 print(isinstance(lis,Iterable)) 5 print(isinstance(lis,Iterator)) 6 结果: 7 True 8 False