列表生成式和生成器

2018-02-27 11:28:47来源:oschina作者:pkookp8人点击

分享

因为不懂,所以写一篇博客。希望一边学一边写,希望在写的过程中能够搞懂这些东西

列表生成式

列表生成式生成的是一个list,当然是用”[]“括起来的


[]的内部是一个for循环,用来生成每一个元素


例如生成了从2到9的一个list:


l = [x for x in range(2,10)]
print(l)
==============================
[2, 3, 4, 5, 6, 7, 8, 9]

for循环可以加if判断,例如可以生成2-9的偶数:


l = [x for x in range(2,10) if x % 2 == 0]
print(l)
==============================
[2, 4, 6, 8]

也可以用多层循环,例如可以生成x遍历2-9,每个x遍历一个3-5的y,当x+y是偶数时,加入list:


l = [x + y for x in range(2,10) for y in range(3, 6) if (x + y) % 2 == 0]
print(l)
==============================
[6, 6, 8, 8, 8, 10, 10, 10, 12, 12, 12, 14]

基本可以等效为:


l=[]
for x in range(2, 10):
for y in range(3, 6):
if (x + y) % 2 == 0:
l.append(x + y)
print(l) 生成器

生成器叫 generator ,与列表生成式不同。列表生成式的结果保存的是计算结果,而 generator 保存的是算法。


可以认为,列表生成式动态的申请了一块内存,用来保存结果。


而generator在得到下一个值前并没有一块内存用来存储这个值,用next的方法可以得到下一个值,并且无法返回到上一个值


一种generator的生成方法和列表生成式很像,只是把[]换成了(),比如:


g = (x for x in range(1, 10) if x % 2 == 0)
print(g)
print("next==========")
print(next(g))
print("for============")
for each in g:
print(each)==============================
at 0x0270C090>
next==========
2
for============
4
6
8


g是一个列表生成式,可以通过for循环获取每个元素,也可以用next获取下一个元素,获取下一个后无法返回到上一个,直到获取完

如果再次调用next,python解释器会抛出一个StopIteration异常


g = (x for x in range(1, 10) if x % 2 == 0)
print(g)
print("next==========")
print(next(g))
print("for============")
for each in g:
print(each)
print("next==========")
print(next(g))==============================
D:/Users/ZXW000/PycharmProjects/untitled/venv1/Scripts/python.exe D:/Users/ZXW000/PycharmProjects/untitled/mygenerator.py
Traceback (most recent call last):
File "D:/Users/ZXW000/PycharmProjects/untitled/mygenerator.py", line 53, in
print(next(g))
StopIteration at 0x006BC090>
next==========
2
for============
4
6
8
next==========
Process finished with exit code 1

使用next抛出的异常会被python解释器捕获并退出程序。而多数程序肯定不愿意把异常处理交给别人做,因为这说明发生了代码设计时未知的错误。因此使用while获取next的时候,可以加入异常处理try... except...finaly。例如:


g = (x for x in range(1, 10) if x % 2 == 0)
print(g)
print("while==========")
while True:
try:
print(next(g))
except StopIteration:
print("g is over")
break==============================
at 0x0223C090>
while==========
2
4
6
8
g is over

另一种可以自己构建一个生成器。使用yield关键字:


def func1():
for i in range(0,5):
print(i)
def func2():
for i in range(0,5):
yield(i)print("func1==========")
func1()
print("func2==========")
g = func2()
while True:
try:
print(next(g))
except StopIteration:
print("g is over")
break==============================
func1==========
0
1
2
3
4
func2==========
0
1
2
3
4
g is over

func1每次调用都会打印0-4总共5个数,但外部变量无法获取到func1内部的每个i


func2则不一样,使用yield关键字后func2就是一个生成器,可以通过for或next获取每个值

func1中print不会阻止函数继续运行,会一直运行直到return为止


对于func2,每次调用next都会执行func2的代码,但只要遇到yield i,函数就返回i,下一次进来时继续从yield后面开始运行;遇到return则抛出一个StopIteration异常


使用yield可以构建出一个内容无限的生成器,例如:


def func3():
i=0
while True:
yield i
i += 1

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台