PHP生成器产生第一个值,然后迭代其余值(PHP generator yield the first value, then iterate over the rest)
我有这个代码:
function generator() {
yield 'First value';
for ($i = 1; $i <= 3; $i++) {
yield $i;
}
}
$gen = generator();
$first = $gen->current();
echo $first . '
';
//$gen->next();
foreach ($gen as $value) {
echo $value . '
';
}
这输出:
First value
First value
1
2
3
我需要'第一个值'才能屈服一次。 如果我取消注释$ gen-> next()行,则发生致命错误:
致命错误:未捕获异常'异常',消息'无法回绕已经运行的生成器'
我怎么解决这个问题?
I have this code:
function generator() {
yield 'First value';
for ($i = 1; $i <= 3; $i++) {
yield $i;
}
}
$gen = generator();
$first = $gen->current();
echo $first . '
';
//$gen->next();
foreach ($gen as $value) {
echo $value . '
';
}
This outputs:
First value
First value
1
2
3
I need the 'First value' to yielding only once. If i uncomment $gen->next() line, fatal error occured:
Fatal error: Uncaught exception 'Exception' with message 'Cannot rewind a generator that was already run'
How can I solve this?
原文:https://stackoverflow.com/questions/33425851
更新时间:2019-11-04 11:48
最满意答案
问题是foreach 尝试重置 (倒带)Generator。 但是如果生成器当前在第一个yield之后,则rewind()会抛出异常。
所以你应该避免使用foreach并使用一段while
$gen = generator();
$first = $gen->current();
echo $first . '
';
$gen->next();
while ($gen->valid()) {
echo $gen->current() . '
';
$gen->next();
}
The problem is that the foreach try to reset (rewind) the Generator. But rewind() throws an exception if the generator is currently after the first yield.
So you should avoid the foreach and use a while instead
$gen = generator();
$first = $gen->current();
echo $first . '
';
$gen->next();
while ($gen->valid()) {
echo $gen->current() . '
';
$gen->next();
}
2015-10-29
相关问答
问题是foreach 尝试重置 (倒带)Generator。 但是如果生成器当前在第一个yield之后,则rewind()会抛出异常。 所以你应该避免使用foreach并使用一段while $gen = generator();
$first = $gen->current();
echo $first . '
';
$gen->next();
while ($gen->valid()) {
echo $gen->current() . '
';
$gen->
...
你的发生器实际上只循环一次。 一旦用pow2_gen创建, g存储一个生成器; 第一次通过loop ,这个生成器被消耗,并发出StopIteration 。 其他时间通过loop , next(g) (或Python 2中的g.next() )继续抛出StopIteration ,所以实际上g表示一个空序列。 为了使比较更公平,每次循环时都需要重新创建发生器。 你接近这个方法的另一个困难是你正在调用append来构建你的列表,这可能是构建列表的最慢方法。 更多的时候,列表是通过列表解析构建的。 以
...
您可以在属性名称列表上使用递归: function getObjectsOf(def) {
var keys = Object.keys(def),
o = {};
return rec(keys.length);
function* rec(i) {
if (i <= 0) {
let clone = {}; // I assume you want to yield different objects
...
你几乎肯定想和第二个一起去。 减少线条,减少出错的机会。 但是,看到你没有在迭代器之外使用current的东西,我只想优化整个事情: def get_next_batch(my_list):
for item in my_list:
yield [item]
arr = [1,2,3,4,5]
for item in get_next_batch(arr):
print item
侧面点。 总是让你的类继承自python 2.7中的object ,并且不要引发S
...
您需要为发电机使用for..of语法。 这会为可迭代对象创建一个循环。 function* numbers(max) {
let n = 0;
while (n < max) {
yield n++;
}
}
使用它: for (let n of numbers(10)) {
console.log(n); //0123456789
}
文档 You need to use the for..of syntax for generators. This creates
...
使用一个临时变量作为一个简单的“队列”,你可以转发来自任何迭代器的元素,并保留最后一个: def islice_to_last(it):
prev_value = next(it)
for value in it:
yield prev_value
prev_value = value
或更一般地(对于发电机最多x个最后的元件): from collections import deque
import itertools as it
def i
...
所以,你的数据结构对我来说似乎很奇怪,但这里是你想要使用的一般模式: def inorder_keys(self):
if self.head.left is not None:
yield from self.head.left.inorder_keys()
yield self.head_key
if self.head.right is not None:
yield from self.head.right.inorder_keys(
...
在BinaryTree.depth ,您正在递归,但是您没有对递归调用执行任何操作。 例如: self.depth(Node.left)
应该是这样的 for node in self.depth(Node.left):
yield node
在Python 3.3+中,它可以很简单 yield from self.depth(Node.left)
你的“主”中的for循环应该是这样的: for node in depthFirstSearch:
print node
我还
...
yield是一个表达式,它的值是随send发送到发生器的任何值。 如果没有发送, yield的值是None。 在你的例子中, yield from列表中得到值,但表达式本身的yield from的值是None,它在封闭的生成器表达式的每次迭代(即每个range(10)值)都产生。 你的例子相当于: def hmm():
for n in range(10):
yield (yield from bin(n)[2:])
for item in hmm():
prin
...
我将忽略显而易见的事实,即file.method()未在您发布的代码中声明,因此无法在显示时调用。 所以我将你的生成器函数称为method() 。 如果您可以发布有效或至少一致的代码,那将非常有用。 method()返回一个生成器,而不是一个列表。 你可以看到这个 >>> method()
您需要解析生成器。 这可以通过调用list()来完成: finalList += list(method())
现在finalLi
...