yield

Is there a way to efficiently yield every file in a directory containing millions of files?

醉酒当歌 提交于 2019-11-26 14:29:09
问题 I'm aware of os.listdir , but as far as I can gather, that gets all the filenames in a directory into memory, and then returns the list. What I want, is a way to yield a filename, work on it, and then yield the next one, without reading them all into memory. Is there any way to do this? I worry about the case where filenames change, new files are added, and files are deleted using such a method. Some iterators prevent you from modifying the collection during iteration, essentially by taking a

Resetting generator object in Python

戏子无情 提交于 2019-11-26 14:21:43
I have generator object returned by multiple yield. Preparation to call this generator is rather time-consuming operation. That is why I want to reuse generator several times. y = FunctionWithYield() for x in y: print(x) #here must be something to reset 'y' for x in y: print(x) Of course, I'm taking in mind copying content into simple list. Ants Aasma Another option is to use the itertools.tee() function to create a second version of your generator: y = FunctionWithYield() y, y_backup = tee(y) for x in y: print(x) for x in y_backup: print(x) This could be beneficial from memory usage point of

PHP迭代生成器---yield

雨燕双飞 提交于 2019-11-26 14:15:24
1、迭代生成器 生成器的核心是一个yield关键字,一个生成器函数看起来像一个普通的函数,不同的是:普通函数返回一个值,而一个生成器可以yield生成许多它所需要的值。生成器函数被调用时,返回的是一个可以被遍历的对象。 yield和return有点类似,不过不同的是,return会返回值并且终止代码的执行,而yield会返回一个值给循环调用此生成器的代码并且只是暂停执行生成器函数。 function gen_one_tow_three(){ for($i = 1; $i <=3; $i++){ //注意:变量$i的值在不同的yield之间是保持传递的。 yield $i; } } $generator = gen_one_tow_three(); var_dump($generator); echo "<br>"; var_dump($generator instanceof Iterator); echo "<br>"; foreach($generator as $value){ echo $value."\n"; } 输出: object(Generator)#1 (0) { } bool(true) 1 2 3 调用gen_one_tow_three()的时候,里面的代码并没有真正的执行,而是返回一个生成器对象$generator = Generator Object(),

PHP的生成器、yield和协程

泪湿孤枕 提交于 2019-11-26 14:15:18
虽然之前就接触了PHP的yield关键字和与之对应的生成器,但是一直没有场景去使用它,就一直没有对它上心的研究。不过公司的框架是基于php的 协程 实现,觉得有必要深入的瞅瞅了。 由于之前对于 生成器 接触不多,后来也是在看了鸟哥的介绍 在PHP中使用协程实现多任务调度 才有所了解。下面也只是说说我的理解。 迭代和迭代器 在了解生成器之前我们先来看一下迭代器和迭代。迭代是指反复执行一个过程,每执行一次叫做迭代一次。比如普通的遍历便是迭代: $arr = [1, 2, 3, 4, 5]; foreach($arr as $key => $value) { echo $key . ' => ' . $value . "\n"; } 我们可以看到通过 foreach 对数组遍历并迭代输出其内容。在 foreach 内部,每次迭代都会将当前的元素的值赋给 $value 并将数组的指针移动指向下一个元素为下一次迭代坐准备,从而实现顺序遍历。像这样能够让外部的函数迭代自己内部数据的接口就是 迭代器接口 ,对应的那个被迭代的自己就是 迭代器对象 。 PHP提供了统一的迭代器接口: Iterator extends Traversable { // 返回当前的元素 abstract public mixed current(void) // 返回当前元素的键 abstract public

php生成器yield

不问归期 提交于 2019-11-26 14:14:57
上次说了php的 生成器Iterator ,这次说一下yield 迭代生成器 (迭代)生成器也是一个函数,不同的是这个函数的返回值是依次返回, 而不是只返回一个单独的值.或者,换句话说,生成器使你能更方便的实现了迭代器接口.下面通过实现一个xrange函数来简单说明: <?php function xrange($start, $end, $step = 1) { for ($i = $start; $i <= $end; $i += $step) { yield $i; // yield关键字类似return关键字的作用,都是在函数中返回一个值,而return是返回后执行析构函数,终止函数,yield是返回一个值,中断函数,并记住当前位置 } } foreach (xrange(1, 1000000) as $num) { echo $num, "\n"; } 上面这个xrange()函数提供了和PHP的内建函数range()一样的功能.但是不同的是range()函数返回的是一个包含值从1到100万的数组(注:请查看手册). 而xrange()函数返回的是依次输出这些值的一个迭代器, 而不会真正以数组形式返回. 这种方法的优点是显而易见的.它可以让你在处理大数据集合的时候不用一次性的加载到内存中.甚至你可以处理无限大的数据流. 当然,也可以不同通过生成器来实现这个功能

PHP的生成器、yield和协程

喜夏-厌秋 提交于 2019-11-26 14:14:53
PHP的生成器、yield和协程 虽然之前就接触了PHP的yield关键字和与之对应的生成器,但是一直没有场景去使用它,就一直没有对它上心的研究。不过公司的框架是基于php的 协程 实现,觉得有必要深入的瞅瞅了。 由于之前对于 生成器 接触不多,后来也是在看了鸟哥的介绍 在PHP中使用协程实现多任务调度 才有所了解。下面也只是说说我的理解。 迭代和迭代器 在了解生成器之前我们先来看一下迭代器和迭代。迭代是指反复执行一个过程,每执行一次叫做迭代一次。比如普通的遍历便是迭代: $arr = [1, 2, 3, 4, 5]; foreach($arr as $key => $value) { echo $key . ' => ' . $value . "\n"; } 我们可以看到通过 foreach 对数组遍历并迭代输出其内容。在 foreach 内部,每次迭代都会将当前的元素的值赋给 $value 并将数组的指针移动指向下一个元素为下一次迭代坐准备,从而实现顺序遍历。像这样能够让外部的函数迭代自己内部数据的接口就是 迭代器接口 ,对应的那个被迭代的自己就是 迭代器对象 。 PHP提供了统一的迭代器接口: Iterator extends Traversable { // 返回当前的元素 abstract public mixed current(void) // 返回当前元素的键

SyntaxError: Unexpected Identifier (Generators in ES6)

孤街醉人 提交于 2019-11-26 14:08:45
问题 I came up with this simple experiment after reading the documentation on generators from MDN: var nodes = { type: 'root', value: [ { type: 'char', value: 'a' }, { type: 'char', value: 'b' }, { type: 'char', value: 'c' }, ], }; function* recursiveGenerator(node) { if (node.type === 'root') { node.value.forEach(function (subnode) { for (var suffix of recursiveGenerator(subnode)) { yield suffix; } }); } else { yield node.value; } } for (generated of recursiveGenerator(nodes)) { console.log

Lua中的协同程序 coroutine

丶灬走出姿态 提交于 2019-11-26 13:45:52
  Lua中的协程和多线程很相似,每一个协程有自己的堆栈,自己的局部变量,可以通过yield-resume实现在协程间的切换。不同之处是: Lua协程是非抢占式的多线程 ,必须手动在不同的协程间切换,且同一时刻只能有一个协程在运行。并且Lua中的协程无法在外部将其停止,而且有可能导致程序阻塞。 协同程序(Coroutine):   三个状态: suspended (挂起,协同刚创建完成时或者yield之后)、 running (运行)、 dead (函数走完后的状态,这时候不能再重新resume)。   coroutine.create(arg):根据一个函数创建一个协同程序,参数为一个函数   coroutine.resume(co):使协同从挂起变为运行(1)激活coroutine,也就是让协程函数开始运行;(2)唤醒yield,使挂起的协同接着上次的地方继续运行。该函数可以传入参数   coroutine.status(co):查看协同状态   coroutine.yield():使正在运行的协同挂起,可以传入参数   resume函数的两种用途虽然都是使协同挂起,但还是有些许差异的,看下面这个例子: coroutineFunc = function (a, b) for i = 1, 10 do print(i, a, b) coroutine.yield() end

生成器

℡╲_俬逩灬. 提交于 2019-11-26 12:46:50
前面我们已经好几次提到了生成器的概念。这里对其简要介绍一下。 有时候,序列或集合内的元素的个数非常巨大,如果全制造出来并放入内存,对计算机的压力是非常大的。比如,假设需要获取一个10**20次方如此巨大的数据序列,把每一个数都生成出来,并放在一个内存的列表内,这是粗暴的方式,有如此大的内存么?如果元素可以按照某种算法推算出来,需要就计算到哪个,就可以在循环的过程中不断推算出后续的元素,而不必创建完整的元素集合,从而节省大量的空间。在Python中,这种一边循环一边计算出元素的机制,称为生成器:generator。 通过圆括号可以编写生成器推导式: >>> g = (x * x for x in range(1, 4)) >>> g <generator object <genexpr> at 0x1022ef630> 可以通过next()函数获得generator的下一个返回值,这点和迭代器非常相似 >>> next(g) 1 >>> next(g) 4 >>> next(g) 9 >>> next(g) Traceback (most recent call last): File "<pyshell#14>", line 1, in <module> next(g) StopIteration 但更多情况下,我们使用for循环。 for i in g: print(i)

Nested yield return with IEnumerable

陌路散爱 提交于 2019-11-26 12:25:48
问题 I have the following function to get validation errors for a card. My question relates to dealing with GetErrors. Both methods have the same return type IEnumerable<ErrorInfo> . private static IEnumerable<ErrorInfo> GetErrors(Card card) { var errors = GetMoreErrors(card); foreach (var e in errors) yield return e; // further yield returns for more validation errors } Is it possible to return all the errors in GetMoreErrors without having to enumerate through them? Thinking about it this is