---恢复内容开始---
列表生成式:
1 list = [i*i for i in range(20)] # 这就是一个列表生成式 2 print(list) 3 # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361] 4 list1 = [i if i < 8 else i*i for i in range(10,20)] # 可以进行三元运算. 5 print(list1) 6 # [110, 132, 156, 182, 210, 240, 272, 306, 342, 380]
生成器:在Python中,这种一边循环一边计算的机制,称为生成器:generator。
特性:
1.只能往后面生成,不能返回到原来的值
2.超过生成范围后,会停止生成,并报错。
生成器的创建方式:
1.通过列表生成式来创建 (i for i in range(100)
2.通过函数来创建.
a = [i for i in range(10000)] # 列表生成式 a2 = (i for i in range(10000)) # 这个就是一个生成器.但是怎么取数据呢? print(a2) # 我们print(a2),发现返回的是一个内存地址.那我们可以用next(a2)的方法来取数据. # 以下代码是在交互模式下进行的 a2 = (i for i in range(1000)) next(a2) 0 next(a2) 1 next(a2) 2 next(a2) 3
a3 = (i for i in range(5)) next(a3) 4 next(a3) Traceback (most recent call last): File "<input>", line 1, in <module> StopIteration #我们手动调用的时候,调到最后一个的时候,再往下调就会出错.可以用for循环调用.就不会报错了 for i in a3: print(i)
python2中 range=list
xrange = 生成器
python3 range =生成器
没有xrange
yield:
yield 和 return区别:
yield 返回数据,并冻结当前的执行过程。
return 返回并终止函数。
当调用next的时候,唤醒冻结的函数执行过程。直到遇到下一次yield。
函数有了yield之后:
1.函数名加()就就得到了生成器。
2.return 在生成器里,代表生成器终止,直接报错。
def fblq(num): n, a, b = 0, 0, 1 while n < num: print('我在yield之前.') yield b #把函数的执行过程冻结在这一步,并把b返回给外面的next(). print(b) a, b = b, a+b n +=1 else: return 0 f = fblq(15) next(f) next(f) next(f) next(f) # 有yield,函数调用时,不会执行。只是生成了一个生成器对象。 # 我在yield之前. # 1 # 我在yield之前. # 1 # 我在yield之前. # 2 # 我在yield之前.
1 # 函数的方式创建生成器 2 3 def range1(n): 4 count = 0 5 while count <n: 6 print(count) 7 count +=1 8 yield count # 返回数据并冻结当前的执行状态. 9 10 11 new = range1(10) 12 next(new) 13 next(new)
14 new.__next__() # 和next(new)一样
Send方法:
1 def range1(n): 2 count = 0 3 while count <n: 4 print(count) 5 count +=1 6 singe = yield count # 返回数据并冻结当前的执行状态. 7 if singe == "stop": # 当接收的信号是stop时,就退出循环. 8 break 9 10 new = range1(100) 11 12 next(new) 13 next(new) 14 new.__next__() 15 new.send("stop") #send 唤醒生成器继续执行并发送一个信号.next只唤醒生成器继续执行
迭代器:
可以直接作用于for
循环的数据类型有以下几种:
一类是集合数据类型,如list
、tuple
、dict
、set
、str
等;
一类是generator
,包括生成器和带yield
的generator function。
这些可以直接作用于for
循环的对象统称为可迭代对象:Iterable
。
判断一个对象是否是一个可迭代对象:
from collections import Iterable li = [1,2,3,4,5,6,7,8,9,0] print(isinstance(li,Iterable)) # 判断一个对象是否是可迭代对象.是返回Trure,否返回False
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。
生成器可以用for和next来取值.可迭代对象只能用for进行迭代取值.
判断一个对象是否是Iterator对象:
from collections import Iterator print(isinstance([],Iterator)) # 判断一个可迭代对象是不是一个迭代器 print(isinstance((i for i in range(100)), Iterator)) # 目前只有生成器是迭代器.迭代器的一个重要的标志就是可以next
生成器都是Iterator
对象,但list
、dict
、str
虽然是Iterable
,却不是Iterator
。
把list
、dict
、str
等Iterable
变成Iterator
可以使用iter()
函数:
from collections import Iterator print(isinstance(iter([]),Iterator)) # 判断一个可迭代对象是不是一个迭代器 print(isinstance(iter("adfc"), Iterator))
你可能会问,为什么list
、dict
、str
等数据类型不是Iterator
?
这是因为Python的Iterator
对象表示的是一个数据流,Iterator对象可以被next()
函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration
错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()
函数实现按需计算下一个数据,所以Iterator
的计算是惰性的,只有在需要返回下一个数据时它才会计算。
Iterator
甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。
小结
凡是可作用于for
循环的对象都是Iterable
类型;
凡是可作用于next()
函数的对象都是Iterator
类型,它们表示一个惰性计算的序列;
集合数据类型如list
、dict
、str
等是Iterable
但不是Iterator
,不过可以通过iter()
函数获得一个Iterator
对象。