列表生成式(使用的是中括号)
[ 函数或运算方法 for 元素 in 可迭代对象 ]
列表生成式先将列表准备好,然后依次将元素带入函数或运算方法中进行操作,并依次返回值
所以可以使用列表切片的方式操作数据。如 :c [100]是可以的
示例1:
[i*2 for i in range(10)]
Out[3]:
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
示例2:
def add(i):
i *=10
print(i)
resuls = [add(i) for i in range(10)]
print(resuls)
生成器(使用的是小括号)
( 函数或运算方法 for 元素 in 可迭代对象)
生成器没法用列表切片的方式取值 如:c [100] 是错误的。
生成器只能记住当前位置,只能用 __next__()方法 获取下一个数据。而且不能返回取之前的数据。
##通过函数做了一个生成器
def fib(max):
n,a,b = 0,0,1
while n< max:
##要想返回什么,就把 yield 放到那个位置。yield是保存了函数的中断状态,下一次还回到这个位置
yield b ##通过yield 在单线程下可以实现并发效果。
a,b = b,a+b
n +=1
# print(fib(100))
##变成生成器的函数。不需要等待函数全部生成,可以暂时中断函数运行,需要的时候再调用
f = fib(100)
print(f.__next__())
print('----------我是插进来运行的东西--------')
print(f.__next__())
print('----------我又插进来一下--------')
print(f.__next__())
print(f.__next__())
用函数实现生成器
还可以通过yield实现在单线程下的情况下实现并发运算的效果
代码1:说明send()对yield的作用
def consumer(name):
print('%s 准备吃包子' %name)
while True:
##yield保存当前状态,
baozi = yield ##走到这就返回,下面的语句不执行
print('包子[%s]被 [%s] 吃了'% (baozi,name))
c = consumer('dralon')
c.__next__()##取值
b1 = '韭菜包子'
c.send(b1)##send把b1的值传递进函数,被yield接收到,并赋值给了'baozi'
##send 调用yield,同时给yield传值。
##__next__只是调用yield
c.__next__()
##运行结果:
# dralon 准备吃包子
# 包子[韭菜包子]被 [dralon] 吃了 (send 调用yield,同时给yield传值。)
# 包子[None]被 [dralon] 吃了 (__next__只是调用yield)
代码2,实现单线程下并发运算的效果
import time
def consumer(name):
print('%s 准备吃包子' %name)
while True:
##yield保存当前状态,
baozi = yield ##走到这就返回,下面的语句不执行
print('包子[%s]被 [%s] 吃了'% (baozi,name))
def producer(name):
c1 = consumer('A----') ##c1开始调用consumer函数
c2 = consumer('----B') ##c2开始调用consumer函数
c1.__next__() ##c1取第一次运行,会在yield的位置停下来
c2.__next__()##c1取第一次运行,会在yield的位置停下来
print('我开始做包子啦!')
for i in range(3):
time.sleep(1)
print('做了一个包子,分两半')
c1.send(i) ##c1调用yield,并将值传给了yield,所以consumer函数有继续运行下去
c2.send(i) ##c2调用yield,并将值传给了yield,所以consumer函数有继续运行下去
producer('dralon')
运行结果:
A---- 准备吃包子
----B 准备吃包子
我开始做包子啦!
做了一个包子,分两半
包子[0]被 [A----] 吃了
包子[0]被 [----B] 吃了
做了一个包子,分两半
包子[1]被 [A----] 吃了
包子[1]被 [----B] 吃了
做了一个包子,分两半
包子[2]被 [A----] 吃了
包子[2]被 [----B] 吃了