周一,雨,记录生活分享点滴
参考博客1:https://www.cnblogs.com/alex3714/articles/5765046.html
参考博客2:https://www.cnblogs.com/yuanchenqi/articles/5769491.html
Python版本:3.5
列表生成式
实现:列表[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],每个值三次方的结果
def f(n): return n**3 a = [f(x) for x in range(10)] print(a) # [0, 1, 8, 27, 64, 125, 216, 343, 512, 729] # print(type(a)) # <class 'list'> # -----简化一下----- a = [n**3 for n in range(10)] print(a) # [0, 1, 8, 27, 64, 125, 216, 343, 512, 729] # print(type(a)) # <class 'list'>
赋值方式
t = ('123', 8, 12) # 元组、列表都可以 a, b, c = t # 等同于a=t[0] b=t[1] c=t[2] print(a) # 123 print(b) # 8 print(c) # 12
生成器
生成器(generator):一边循环一边计算的机制
列表生成式的[]
改成()
# L是一个list L = [x * x for x in range(10)] print(L) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] # g是一个generator g = (x * x for x in range(10)) print(g) # <generator object <genexpr> at 0x000002200EBAD518>
next(不合理)
g = (x * x for x in range(10)) # print(g) # <generator object <genexpr> at 0x000002200EBAD518> print(next(g)) # 0 print(next(g)) # 1 print(next(g)) # 4 print(next(g)) # 9 print(next(g)) # 16 print(next(g)) # 25 print(next(g)) # 36 print(next(g)) # 49 print(next(g)) # 64 print(next(g)) # 81 print(next(g)) # StopIteration 因为范围是10,为0-9,不包括10,所以报错
for循环(正常)
g = (x * x for x in range(10)) for n in g: print(n) # 0 # 1 # 4 # 9 # 16 # 25 # 36 # 49 # 64 # 81
斐波拉契数列
斐波拉契数列
斐波拉契数列用列表生成式写不出来,可以用函数打印
def fib(max): n, a, b = 0, 0, 1 while n < max: print(b) a, b = b, a + b n = n + 1 return 'done' fib(10) # 10可以为任意数,按需定义
fib
函数变成generator
fib
函数变成generator方式:把print(b)
改为yield b
def fib(max): n, a, b = 0, 0, 1 while n < max: yield b # 将 print(b) 改为 yield b a, b = b, a+b n += 1 return 'done' f = fib(6) print(f) # <generator object fib at 0x000002B870B2D518>
generator和函数的执行流程
函数是顺序执行,遇到 return 语句或者最后一行函数语句就返回。
而变成generator的函数,在每次调用 next() 的时候执行,遇到 yield 语句返回,再次执行时从上次返回的 yield 语句处继续执行。
data = fib(10) print(data) print(data.__next__()) print(data.__next__()) print("干点别的事") print(data.__next__()) print(data.__next__()) print(data.__next__()) print(data.__next__()) print(data.__next__()) #输出 <generator object fib at 0x101be02b0> 1 1 干点别的事 2 3 5 8 13
通过生成器 yield 实现伪并发
import time def consumer(name): print("%s 准备吃包子啦!" % name) while True: baozi = yield print("包子[%s]来了,被[%s]吃了!" % (baozi, name)) def producer(name): c = consumer('A') # c与c2是生成器对象 c2 = consumer('B') c.__next__() c2.__next__() print("Chung开始准备做包子啦!") for i in range(10): time.sleep(1) print("做了2个包子!") c.send(i) c2.send(i) producer("Chung") # 通过生成器实现协程并行运算
迭代器
Iterable
直接作用于for
循环的对象统称为可迭代对象:Iterable
一类是集合数据类型,如list
、tuple
、dict
、set
、str
等;
一类是generator
,包括生成器和带yield
的generator function。
可以使用isinstance()
判断一个对象是否是Iterable
对象:
from collections import Iterable print(isinstance([], Iterable)) # True print(isinstance({}, Iterable)) # True print(isinstance('abc', Iterable)) # True print(isinstance((x for x in range(10)), Iterable)) # True print(isinstance(100, Iterable)) # False
Iterator
可以被next()
函数调用并不断返回下一个值的对象称为迭代器:Iterator
。
可以使用isinstance()
判断一个对象是否是Iterator
对象:
from collections import Iterator print(isinstance((x for x in range(10)), Iterator)) # True print(isinstance([], Iterator)) # False print(isinstance({}, Iterator)) # False print(isinstance('abc', Iterator)) # False
生成器都是Iterator
对象,但list
、dict
、str
虽然是Iterable
,却不是Iterator
。
Iter()
把list
、dict
、str
等Iterable
变成Iterator
可以使用iter()
函数:
from collections import Iterator print(isinstance(iter([]), Iterator)) # True print(isinstance(iter('abc'), Iterator)) # True
小结
1. 生成器都是迭代器,但迭代器不一定都是生成器
2. 生成器有两个条件:
(1)有iter方法,
(2)有next方法
3. for循环内部三件事:
(1)调用可迭代对象的iter方法返回一个迭代器对象;
(2)不断调用迭代器对象的next方法;
(3)处理StopIteration
# ***********列表生成式*********** [x*2 for x in range(10)] # ***********生成器(generator object)*********** 创建生成器的两种方式: 1 (x*2 for x in range(10))>>>>>>>generator object 2 def f(): yield f()>>>>>>>generator object 生成器的方法: 1 next(f())-----------------计算出一个值 注意:生成器在创建的时候已经决定了能计算出值的个数,调用next的次数超过这个值就会报StopIteration 遍历所有元素可以通过for循环: for i in [1, 2, 3]: print i for 循环内部做了三件事: 1 调用对象的iter()方法,返回一个迭代器对象 2 while: try: i=next(list_Iterator) except StopIteration: break 2 send(): f().send(None) # 等价于next(f()) # ***********迭代器*********** 满足迭代器协议: 1 内部有next方法 2 内部有iter方法 li=[1,2,3]:Iterble(内部有iter方法)>>>>>>>iter(li):list_Iterator i=iter(li):list_Iterator 1 next(i)-----------------计算出一个值 注意:迭代器在创建的时候已经决定了能计算出值的个数,调用next的次数超过这个值就会报StopIteration 遍历所有元素可以通过for循环: for i in [1, 2, 3]: print i for 循环内部做了三件事: 1 调用对象的iter()方法,返回一个迭代器对象 2 while: try: i=next(list_Iterator) except StopIteration: break 2 send(): f().send(None) # 等价于next(f())