先说一下列表生成式:
它还是比较常用的,生成一个简单的数组:
list_a=list(range (1,11))
>>>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
在复杂的场景下,我们不可能一个一个的append方式插入数据,可以利用列表生成式很简单的生成:
print([x*5+2 for x in list(range(1 ,10)) if x%2==1])
》》》[7, 17, 27, 37, 47]
生成器:
列表生成式需要一次性生成所有的元素,如果需要每次按照需求来生成,而不是一次性全部生成(节约内存:创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了),在Python中,这种一边循环一边计算的机制,称为生成器:generator
创建一个生成器很简单,只需要将列表生成式 的[] 改为()便OK,
L=[x*5+2 for x in list(range(1 ,10)) if x%2==1]
print(L)
#>>>[7, 17, 27, 37, 47]
generator_a = (x*5+2 for x in list(range(1 ,10)) if x%2==1)
print(generator_a)
#>>><generator object <genexpr> at 0x00000113CB8C87C8>
可以看出,L是一个list,而generator_a是一个生成器,generator保存的是算法,可以通过next()h获取数据:
generator_a = (x*5+2 for x in list(range(1 ,10)) if x%2==1)
print(next(generator_a))
>>>7
print(next(generator_a))
>>>17
print(next(generator_a))
>>>27
这种方式显然很麻烦,直接用for循环可以替代,
generator_a = (x*5+2 for x in list(range(1 ,10)) if x%2==1)
for x in generator_a:
print(x)
但是有的需求不能直接用列表生成式写出来,但是可以用函数表达式写出来:
#普通函数表达式写法
def teshu_generat(num):
a,b=0,10
while num>b:
print(num)
if num>a:
a+=2
num-=a
return 'OK'
print(teshu_generat(20))
# >>> 20
# >>> 18
# >>> 14
# >>> OK
#转换为生成器,只需要把输出转换一下写法:
def teshu_generat1(num):
a,b=0,10
while num>b:
yield num
if num>a:
a+=2
num-=a
return 'OK'
end =teshu_generat1(20)
print(end)
#>>> <generator object teshu_generat1 at 0x0000016CF77D87C8>
for x in end:
print(x)
# >>> 20
# >>> 18
# >>> 14
需要注意的是:用for循环调用generator时,发现拿不到generator的return语句的返回值。如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中:
while True:
try:
x =next(end)
print('元素是:',x)
except StopIteration as e:
print('Generator return value:', e.value)
break
# >>> 20
# >>> 18
# >>> 14
# >>> Generator return value: None