day13-Python列表生成式、迭代器和生成器
一.列表生成式
1.生成列表
a = [1,2,3,4,5,6]
要求:列表中的每个元素加上2
a = [1,2,3,4,5,6] for index,value in enumerate(a): a[index] += 2 print(a) # [3, 4, 5, 6, 7, 8]
2.列表生成式
a = [i+2 for i in range(1,7)] print(a) # [3, 4, 5, 6, 7, 8]
print([value * 100 for index,value in enumerate(range(20)) if index < 20]) # [0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900]
二.生成器(ganerator)
通过列表生成式,可以直接创建一个列表,但是如果数据量非常大的话,常常会受到电脑内存的限制,列表的容量也是有限的。但是如果列表使用某种算法计算出来,我们可以在循环的过程中不断的推出后续的元素,这样就不必预先计算完整的list,从而节省大量的空间。
PS:在Python中,这种一边计算一边的机制被称之为生成器(ganerator)
1.生成器的特征
- 生成器只有在调用的时候才会执行生成对应的数据
- 生成器只会记录当前的位置,无法往前或者向后求取数据
- 有一个__next__()方法 或者next()内置方法可以获取生成器的值
2.生成器的生成方法
将列表的[]写成(),就会生成一个生成器(ganerator)
L = [i*i for i in range(8)] # 列表表达式生成列表 print(L) # [0, 1, 4, 9, 16, 25, 36, 49] g = (i*i for i in range(8)) # 生成器 print(g) # <generator object <genexpr> at 0x00000000028F47E0>
3.使用函数生成生成器
如果一个函数中有一个yield关键字,就是一个生成器
斐波那契数列:每个数等于前两个数相加。如:1 1 2 3 5 8
def fib(num): n,a,b = 0,0,1 while n < num: # yield b a,b = b,a+b yield a # 函数的中断点,可以通过for循环或者next方法再次回到函数 n = n + 1 fib = fib(10) print(fib.__next__()) # 1 for i in fib: print(i) # 1 2 3 5 8 13 21 34 55
4.生成器并行
import time def consumer(name): print("%s 准备吃包子啦!" %name) while True: baozi = yield print("包子[%s]来了,被[%s]吃了!" %(baozi,name)) c = consumer("ww") c.__next__() # b1= "韭菜馅" # c.send(b1) # c.__next__() def producer(): c = consumer('A') c2 = consumer('B') c.__next__() c2.__next__() print("老子开始准备做包子啦!") for i in range(10): time.sleep(1) print("做了1个包子,分两半!") c.send(i) c2.send(i) producer()
三.迭代器
首先说明,上一节的生成器也是一个迭代器(Iterator)。
1.迭代器定义
可以被next()函数或者a.__next__(a是迭代器),不断返回下一个值的对象被称为迭代器。
a = (i for i in range(1,7)) print(next(a)) # 1 print(a.__next__()) # 2 print(next(a)) # 3 print(a.__next__()) # 4 print(next(a)) # 5 print(a.__next__()) # 6
2.可用for循环进行读取的数据类型
- 一种是:list、tuple、dict、set、str(本身不是迭代器)
- 另一种是:generator(生成器)
2.1 iter()
可以用iter()内置方法把list、tuple、dict、set、str转化成迭代器。
a = [1,2,3,4,5,6,7] b = iter(a) print(b) # <list_iterator object at 0x0000000002690668>
2.2 isinstance()
判断一个对象是否为迭代器、
from collections import Iterator a = [1,2,3,4,5,6,7] if isinstance(a,Iterator): print(a) # 结果为空。a不是迭代器 b = iter(a) # 将列表a转换成迭代器 if isinstance(b,Iterator): print(b) # <list_iterator object at 0x0000000002690668> b不是迭代器