[python] 再来理解迭代器 生成器
1,原理
iter,简单可以理解成完成的list对象
gen,实际通过next方法,没执行一次就 保留最新的结果
2,区别
(i for i in a)
[i for i in b]
3,使用场景
数据比较
4,技巧
yield
#0629 iter and genalrator ''' def is_iterable(param): try: iter(param) return True except TypeError: return False params=[ 1234, '1234', [1,2,3,4], set([1,2,3,4]), {1:1,2:2,3:3,4:4}, (1,2,3,4) ] for param in params: print('{} is iterable? {}'.format(param,is_iterable(param))) ''' # 显然除了 第一个是number,其他不管是 字符串,list ,set,还是dict等都是iterable的 # 什么是生成器generator 呢 ? ''' import os import psutil def show_memory_info(hint): pid=os.getpid() p=psutil.Process(pid) info=p.memory_full_info() memory=info.uss/1024./1024 print('{} use {} MB '.format(hint,memory)) #show_memory_info('QQ.exe') def test_iterator(): show_memory_info('initing iterator') list_1=[i for i in range(10000000)] show_memory_info('after iterator initiated') print(sum(list_1)) show_memory_info('after sum called') def test_generator(): show_memory_info('initing generator') list_2=(i for i in range(10000000)) show_memory_info('after generator initiated') print(sum(list_2)) show_memory_info('after sum called') %time test_iterator() %time test_generator() ''' ####################### out put below############################## ''' after iterator initiated use 429.62109375 MB 49999995000000 after sum called use 429.62109375 MB Wall time: 1.46 s initing generator use 41.23046875 MB after generator initiated use 41.23046875 MB 49999995000000 after sum called use 41.43359375 MB Wall time: 826 ms ''' # 直观感受就是 第一个使用内存多,而且要慢一点,据说 后者是在进行这种累加计算的时候,并不保留全部中间值,而是内次next之后就更新一下值 # #''' # 什么事OOM错误 # 迭代器相对有限,生成器 可以一直next 下午 ''' M=[1,6,2,4,5,2,8,3,2] print(*enumerate(M)) print(list(enumerate(M))) # 传统方式 def index_normal(L,target): result=[] for i,num in enumerate(L): if num==target: result.append(i) return result print(index_normal(M,2)) # 生成器方式 def index_generator(L,target): for i,num in enumerate(L): if num==target: yield i print(*index_generator(M,2)) print (list(index_generator(M,2))) # 看到这个的区别的 , 生成器不用定义 result 也不用返回, 当循环一直进行的情况下,就自动添加新的结果到结果集中,当然 要用一下 list 进行转换 ''' '''4 # 最后 上一个 有点抽象的, 作用是 判断a是否 是b的一个 子序列 # 例子如下 def is_subsequence(a,b): b = iter(b) return all(i in b for i in a) list0=[1,2,3,4,5] list1=[1,3,4] list2=[1,4,3] print(is_subsequence(list1,list0)) print(is_subsequence(list2,list0)) ''' #'''5 def is_subsequence(a,b): b=iter(b) print(b) # 转型iter 没有数据变化 gen=(i for i in a) print(gen) # 转型 gen,没有数据变化 for i in gen: print(i) # 展示 gen的数据 gen=((i in b ) for i in a) print(gen) # 如何理解, # 这里 gen 相当于 把a的每个元素作为循环变量, 逐个在b里边进行比对,如果通过1一次以上的next获取,则返回true ,有一点不太理解的就是 每次 for i in gen: print(i) return all(((i in b ) for i in a)) # 这个 all 其实是把 整个a作为元素看看是否在b中,但是无论如何返回的都是否定的--? list0=[1,2,3,4,5] list1=[1,3,4] list2=[1,4,3] list3=[1,2,3,4,5] print(is_subsequence(list1,list0)) print(is_subsequence(list2,list0)) print(is_subsequence(list3,list0)) #'''5

浙公网安备 33010602011771号