yield

生成器

坚强是说给别人听的谎言 提交于 2020-01-06 22:02:20
生成器 生成器 生成器仅仅保存了一套生成数值或者对象的算法,并且没有让这个算法现在就开始执行,而是我什么时候调它,它什么时候开始计算一个新的值,并给你返回。 为何要用生成器 存储海量的数据会占用内存资源,如果我们可以根据算法推算后面的数据,什么时候需要的时候就去生成,这样将极大地减少内存占用。 创建生成器 1. 列表生成式的[]改成() L = [x * x for x in range(10)] print(L) G = (x * x for x in range(10)) print(G) print(next(G) 执行结果 [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] <generator object <genexpr> at 0x02739DB0> 0 next是生成器能迭代的关键, next(G)等价于G.__next__() ,调用他就生成一个新的对象并返回。 2. yield 在函数里面有yield关键字,函数就变成了一个生成器。当调用next()函数时,就相当于生成下一个对象(统称),这一次next开始的地方是接着上一次next停止的地方执行的,即yield之后继续执行,到yield处返回生成的对象。 例子 def fun(): print('run fun') while True: rtn = yield 6 print('rtn

yield slower than return. why?

落花浮王杯 提交于 2020-01-04 14:12:42
问题 I wrote two function f and g with same functionality def f(l, count): if count > 1: for i in f(l, count-1): yield i + 1 else: yield from l for i in f(range(100000),900): pass print('f') and def g(l, count): if count > 1: tmp = [] for i in g(l, count-1): tmp.append(i+1) return tmp else: return l for i in g(range(100000),900): pass print('f') and i I think f shuold be faster but g is faster when in run it time for g real 0m5.977s user 0m5.956s sys 0m0.020s time for f real 0m7.389s user 0m7.376s

Bug on Keras fit_generator, running few steps more than it should

瘦欲@ 提交于 2020-01-04 05:51:20
问题 I found fit_generator() would run few steps more than it should. I set steps_per_epoch=100 . i and k both start from 0. But at the end of training process, it will print out k = 109 . This situation only occurs when validation data are added. def data_generate(xfd, yfd, x_line_offset, y_line_offset): while True: k = 0 x_line_offset, y_line_offset = shuffle_list(x_line_offset, y_line_offset) for i in range(100): print('i = {}'.format(i)) print('k = {}'.format(k)) k += 1 x_train = get_line_by

How to make yield work in debug mode?

会有一股神秘感。 提交于 2020-01-04 05:22:50
问题 I am working with ipdb and yield. I noticed the yield does not act as expected when using it with ipdb. Specifically, this code when being debugged with ipdb (and pressing the 'n' charcter in the key board simply skips the yield command instead of returning from the function) def cats(): print(-1) yield for i in range(4): print(i) yield import ipdb ipdb.set_trace() x = cats() next(x) next(x) next(x) How could this be resolved? 回答1: Both ipdb and pdb need a statement after the yield for them

协程

扶醉桌前 提交于 2020-01-04 05:11:24
1、协程的理解 协程,又称微线程,纤程。英文名Coroutine,是一种用户态的轻量级线程。 注意:   1. python的线程属于内核级别的,即由操作系统控制调度(如单线程一旦遇到io就被迫交出cpu执行权限,切换其他线程运行)   2. 单线程内开启协程,一旦遇到io,从应用程序级别(而非操作系统)控制切换 协程优点:   1. 协程的切换开销更小,属于程序级别的切换,操作系统完全感知不到,因而更加轻量级   2. 单线程内就可以实现并发的效果,最大限度地利用cpu 协程缺点:   1.协程的本质是单线程下,无法利用多核,可以是一个程序开启多个进程,每个进程内开启多个线程,每个线程内开启协程   2.协程指的是单个线程,因而一旦协程出现阻塞,将会阻塞整个线程 协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方(线程调度时候寄存器上下文及栈等保存在内存中),在切回来的时候,恢复先前保存的寄存器上下文和栈。因此:协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态,换种说法:进入上一次离开时所处逻辑流的位置。 子程序,或者称为函数,在所有语言中都是层级调用,比如A调用B,B在执行过程中又调用了C,C执行完毕返回,B执行完毕返回,最后是A执行完毕。 所以子程序调用是通过栈实现的

python之协程

心不动则不痛 提交于 2020-01-04 05:11:02
一、协程理论 1.1 协程产生的背景 之前我们学习了线程、进程的概念,了解了在操作系统中 进程是资源分配的最小单位,线程是CPU执行的最小单位。 随着我们对于效率的追求不断提高, 基于单线程来实现并发 又成为一个新的课题,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发。这样就可以节省创建线进程所消耗的时间。 本节我们就基于单线程来实现并发,首先我们要回顾一下并发的本质: 切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作系统强制控制) (1)该任务发生了阻塞 (2)该任务计算时间过长或有个更高级的程序替代它 ps:在介绍进程理论时,提及进程的三种执行状态,而线程才是执行单位,所以也可以将上图理解为线程的三种状态 注意点1 第二种情况本质上并不能提高效率,只是为了cpu能雨露均沾,实现看起来所有任务被“同时”执行,如果多个任务是纯计算的,单纯的切换反而会降低效率。 1.2 yield实现并发 我们通过yield验证,yield本身就是一种在单线程下可以保存任务运行状态的方法,我们来简单复习一下: #1 yiled可以保存状态,yield的状态保存与操作系统的保存线程状态很像,但是yield是代码级别控制的,更轻量级 #2 send可以把一个函数的结果传给另外一个函数,以此实现单线程内程序之间的切换 yield实现并发的缺点: (1

python并发编程(二):协程

三世轮回 提交于 2020-01-04 05:08:58
'''协程: 1. 协程的定义: 1) 是一种用户态的轻量级线程, 即协程是由用户程序自己控制调度的 2) 是一种协作而非抢占式的处理并发方式, A --> B ---> A --> C 3) 协程的切换属于程序级别的, 操作系统不需要切换 2. 协程的特点: 1) 协程本身是一个线程, 是用户态的切换 2) 相比线程优点: 1> 切换没有消耗 2> 修改共享程序不需要加锁 3) 相比线程缺点: 一旦引入协程,就需要检测单线程下所有的IO行为, 实现遇到IO就切换,少一个都不行,因为一旦一个任务阻塞了,整个线程就阻塞了 3. 并发要求: 1) 要控制多个任务之间的切换 2) 切换之前要把当前任务状态保存下来 (yield, greenlet无法检测IO) 3) 可以自动检测IO操作, 在IO阻塞下发生切换 (geven可以检测IO) ''' # 协程'''协程实现: 1. 生成器: yield, next(g), g.send(value) 用法: yield # 可以保存状态 g = generator() # 创建生成器 next(g) # 检测到最近yield位置, 执行yield之前的代码 g.send(value) # 检测当前yield的位置,把值通过该yield传入,执行下一个yield到该yield之间的代码, 然后返回 2. greenlet:

Trouble unpacking list in a customized way

时光总嘲笑我的痴心妄想 提交于 2020-01-04 03:32:10
问题 I'm trying to unpack some list which I've yielded within get_item() function. I know I can get desired result If I used return instead of yield . I've tried: def get_item(): yield ["k","y","t"] if __name__ == '__main__': for item in get_item(): print(item) Output I'm getting: ['k', 'y', 't'] Output I wanna get: k y t What possible change should I bring about to get the desired result keeping yield as it is? 回答1: As of Python 3.3, you can use yield from : def get_item(): yield from ["k","y","t

Non-blocking generator on Python

夙愿已清 提交于 2020-01-04 02:52:26
问题 I'm using a generator function from the requests module in a QT-Application, pretty much the same as in the requests-streaming example: import json import requests def get_stream(): r = requests.get('http://httpbin.org/stream/20', stream=True) for line in r.iter_lines(): if line: yield json.loads(line) def consume_stream(): for message in get_stream(): #do something However, when there is no incoming response (f.e. irregularly incoming tweets from Twitters Streaming API), the generator get

Why does `yield from` in a generator expression yield `None`s?

∥☆過路亽.° 提交于 2020-01-03 17:45:14
问题 I have the following code: import itertools for c in ((yield from bin(n)[2:]) for n in range(10)): print(c) The output is: 0 None 1 None 1 0 None 1 1 None ... etc. Why do the None s appear? If I instead have: def hmm(): for n in range(10): yield from bin(n)[2:] for c in hmm(): print(c) Then I get what I would expect: 0 1 1 0 1 1 ... etc. Further, is there a way to write it as the generator expression to get the same result as the latter? 回答1: yield is an expression, and its value is whatever