#可迭代
l =[i for i inrange(10)]for idx in l:print(idx)#l是可迭代对象,但不是迭代器for i inrange(5):print(i)#range是一个迭代器
通过isinstance判断
判断某个变量是否是一个实例
from collections import Iterable,Iterator
import collections
ll =[1,1,23,4,5]print(isinstance(ll,Iterable))print(isinstance(ll,Iterator))
可以通过iter函数进行转换
from collections import Iterable,Iterator
import collections
ll =[1,1,23,4,5]print(isinstance(ll,Iterable))print(isinstance(ll,Iterator))
s_iter =iter(ll)print(isinstance(s_iter,Iterable))print(isinstance(s_iter,Iterator))
3、生成器
generator:一边循环一遍计算下一个元素的机制/算法
需要满足三个条件
1、每次调用都生产出for循环需要的下一个元素
2、如果达到最后一个,爆出StopIteration异常
3、可以被next函数调用
如何制作一个生成器
1、直接使用
l =[x*x for x inrange(5)]#放在中括号里就是列表生成器
g =(x*x for x inrange(5)#放在小括号里就是生成器print(type(l))print(type(g))
2、如果函数中包含yield,则这个函数就叫生成器
next调用函数,遇到yield返回
defodd():print('Step 1')yield1print('Step 2')yield2print('Step 3')yield3#生成器用next调用
g = odd()#生成生成器
one =next(g)print(one)
two =next(g)print(two)print('*'*20)#for 循环调用生成器deffib(max):
n,a,b =0,0,1while n<max:yield b
a,b = b,a+b
n +=1return'done'
g = fib(5)for i inrange(6):
rst =next(g)print(rst)
4、协程
3.4引入协程,用yield实现
3.5引入协程语法
实现的协程比较好的包:asyncio,tornado,gevent
定义
是为非抢占式多任务产生子程序的计算机程序组件,协程允许不同入口点在不同位置暂停或开始执行任务
从技术角度将,协程就是一个可以暂停执行的函数
协程的实现
yield返回
send调用
defsimple():print('--> start')
x =yieldprint('--> recied',x)
sc = simple()print(1111)next(sc)#预激print(2222)
sc.send('zhexiao')
协程的四个状态
inspect.getgeneratorstate(…) 函数确定,该函数会返回下述字符串中的一个
GEN_CREATED:等待执行开始
GEN_RUNNING:解释器正在执行
GEN_SUSPENED:在yield表达式处暂停
GEN_CLOSED:执行结束
next:预激
defsimple(a):print('--> start')
b =yield a
print('--> recied',a,b)
c =yield a+b
print('--> recied',a,b,c)
sc = simple(5)
aa =next(sc)#预激print(aa)
bb = sc.send(6)print(bb)
cc = sc.send(7)print(cc)
defgen():for c in'AB':yield c
print(list(gen()))defgen_new():yieldfrom"AB"print(list(gen_new()))
委派生成器
包含yield from表达式的生成器函数
委派生成器在yield from 表达式暂停,调用方可以直接把数据发给子生成器
子生成器在把产生的值发给调用方
子生成器在最后,解释器会抛出StopIteration,并且把返回值附加到异常对象上 \
from collections import namedtuple
'''解释
1、外层for循环每次迭代会新建一个grouper实例,赋值给coroutine变量:grouper是委派生成
2、调用next(coroutine),预激委派生成器,此时进入while循环,调用子生成器
3、内层for循环调用coroutine.send(),直接把值传给子生成器
4、内层循环结束,grouper实例依旧在yield from表达式处停留
5、coroutine.send(None)终止average子生成器'''
ResClass = namedtuple('Res','count average')#子生成器defaverager():
total =0.0
count =0
average =NonewhileTrue:
term =yield#None是哨兵值 if term isNone:break
total += term
count +=1
average = total/count
return ResClass(count, average)#委派生成器defgrouper(storages, key):whileTrue:#获取averager的返回值
storages[key]=yieldfrom averager()#客户端代码defclient():
process_data ={'boy2':[39.0,40.8,43.2,40.8,43.1,38.6,41.4,40.6,36.3],'boy1':[1.38,1.5,1.32,1.25,1.37,1.48,1.25,1.49,1.46]}
storages ={}for k, v in process_data.items():#获取协程
coroutine = grouper(storages,k)#预激协程 next(coroutine)#发送数据到协程 for dt in v:
coroutine.send(dt)#终止协程
coroutine.send(None)print(storages)#run
client()
from concurrent.futures import ThreadPoolExecutor
import time
defreturn_future(msg):
time.sleep(3)return msg
#创建一个线程池
pool = ThreadPoolExecutor(max_workers=2)#在线程池中加入2个task
f1 = pool.submit(return_future,'hello')
f2 = pool.submit(return_future,'world')print(f1.done())
time.sleep(3)print(f2.done())print(f1.result())print(f2.result())
9、current中的map函数
map(fn,*iterables,timeout=None)
和map函数类似 - 函数需要异步执行
timeout:超时时间
map 和 submit 使用一个就行
import time, re import os, datetime
from concurrent import futures
data =['1','2']defwait_on(argument):print(argument)
time.sleep(2)return'OK'
ex = futures.ThreadPoolExecutor(max_workers=2)for i in ex.map(wait_on,data):print(i)