在另一个问题中,我得到了一个很好的答案,涉及为中国邮递员问题生成某些集合.
答案是:
def get_pairs(s):
if not s: yield []
else:
i = min(s)
for j in s - set([i]):
for r in get_pairs(s - set([i, j])):
yield [(i, j)] + r
for x in get_pairs(set([1,2,3,4,5,6])):
print x
Run Code Online (Sandbox Code Playgroud)
这将输出以下的期望结果:
[(1, 2), (3, 4), (5, 6)]
[(1, 2), (3, 5), (4, 6)]
[(1, 2), (3, 6), (4, 5)]
[(1, 3), (2, 4), (5, 6)]
[(1, 3), (2, 5), (4, 6)]
[(1, 3), (2, 6), (4, 5)]
[(1, 4), (2, 3), …Run Code Online (Sandbox Code Playgroud) 我经常发现自己写作...... 像这样:
if (condition)
{
yield return whatever;
yield break;
}
Run Code Online (Sandbox Code Playgroud)
我发现必须为标准范例"返回一个值和退出方法"使用两个yield语句非常冗长.我知道我可以,return new List<type>() { whatever };但这会破坏在方法的其余部分使用yield的好处.
是否有更优雅的方法来获取yield return值并退出方法?
我想实现一个惰性迭代器,它在每个调用中产生一个3级嵌套循环中的下一个元素.
scala中有类似于c#的这个片段:
foreach (int i in ...)
{
foreach (int j in ...)
{
foreach (int k in ...)
{
yield return do(i,j,k);
}
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢,Dudu
在javadoc中有说yield方法
导致当前正在执行的线程对象暂时暂停并允许其他线程执行.
Katherine Sierra和Bert Bates的SCJP书中说过
yield()应该做的是使当前运行的线程返回runnable以允许具有相同优先级的其他线程轮到他们.
那么实际的方法是做什么的?
我写了一个读取txt文件的类.该文件由非空行块组成(让我们称之为"部分"),由空行分隔:
line1.1
line1.2
line1.3
line2.1
line2.2
Run Code Online (Sandbox Code Playgroud)
我的第一个实现是读取整个文件并返回列表列表,这是一个列表列表,其中每个部分是一个行列表.这显然是非常可怕的记忆.
所以我重新将它作为列表生成器实现,即在每个循环中,我的类将内存中的整个部分作为列表读取并生成它.
这样更好,但在大型部分的情况下仍然存在问题.所以我想知道我是否可以重新实现它作为发电机的发电机?问题是这个类非常通用,它应该能够满足这两个用例:
将一个小文件读入内存,以便多次循环.列表生成器工作正常,因为用户可以只调用
列表(MyClass的(file_handle))
但是,生成器的生成器在情况2中不起作用,因为内部对象不会转换为列表.
有没有比实现一个显式的to_list()方法更优雅的东西,它会将生成器的生成器转换为列表列表?
所以,我一直在阅读这篇文章,并了解了如何向生成器发送值.
而现在我有点困惑.产量是陈述还是表达?它不像函数一样使用括号语法,所以它看起来像语句.但它返回值,所以它就像表达式.
就在不久前,我已经开始讨论"为什么python没有'如果x = foo():( ...)'?" (为什么我们不能在if语句条件中分配).我说,语句是原子的,所以赋值语句和if语句应该分开.现在,我不知道该怎么想.
==编辑==
我做了我公平的阅读.
http://docs.python.org/2/reference/expressions.html#generator.send - "value参数成为当前yield表达式的结果."
因此,产生HAS值.我明白了,所有的文档都说这是一个陈述,但如果陈述可能有价值,那么表达和陈述之间的差异到底是什么?
另外,我知道什么是生成器,协同程序等等.我需要元语义或文档的语义:D
==最终答案==
让我们有一个具有不时失败的功能的类,但是在一些动作之后它才能完美地运行.
现实生活中的例子是Mysql Query提升,_mysql_exceptions.OperationalError: (2006, 'MySQL server has gone away')但在客户端重新连接后它可以正常工作.
我试过写这个装饰器:
def _auto_reconnect_wrapper(func):
''' Tries to reconnects dead connection
'''
def inner(self, *args, _retry=True, **kwargs):
try:
return func(self, *args, **kwargs)
except Mysql.My.OperationalError as e:
# No retry? Rethrow
if not _retry:
raise
# Handle server connection errors only
# http://dev.mysql.com/doc/refman/5.0/en/error-messages-client.html
if (e.code < 2000) or (e.code > 2055):
raise
# Reconnect
self.connection.reconnect()
# Retry
return inner(self, *args, _retry=False, **kwargs)
return inner
class A(object):
...
@_auto_reconnect_wrapper
def get_data(self):
sql = …Run Code Online (Sandbox Code Playgroud) 我有以下代码:
<?php
function generator() {
yield 'First value';
for ($i = 1; $i <= 3; $i++) {
yield $i;
}
}
$gen = generator();
$first = $gen->current();
echo $first . '<br/>';
//$gen->next();
foreach ($gen as $value) {
echo $value . '<br/>';
}
Run Code Online (Sandbox Code Playgroud)
输出:
First value
First value
1
2
3
Run Code Online (Sandbox Code Playgroud)
我需要“第一个价值”才能产生一次。如果我取消注释$ gen-> next()行,则会发生致命错误:
致命错误:消息为“无法倒带已运行的生成器”的未捕获异常“ Exception”
我该如何解决?
假设我已经创建了一个ES6生成器
function *createFibonacciIterator(a = 0, b = 1) {
yield b;
yield *createFib(b, b + a); // <== QUESTION IS ABOUT THIS LINE
}
Run Code Online (Sandbox Code Playgroud)
然后我使用该生成器获得前20个结果
let fibber = createFibonacciIterator();
for (let ii = 0; ii < 20; ii++) {
console.log(fibber.next());
}
Run Code Online (Sandbox Code Playgroud)
如果我离开*了的yield *createFib(b, b + a);线的东西打破,这是有道理的,因为我不希望产生一个迭代器,但实际价值.
*发电机的技术含义是什么?
昨天,我了解到PHP有一种yield()方法.我不确定它在PHP中的用处.
一位同事表示,它可以帮助SQL语句返回许多行,从而导致潜在的内存问题.我相信他在提到fetchAll().但是,除了使用之外fetchAll(),还可以逐个使用fetch()和处理行.因此,yield()解决他所指的问题并不是关键.
我在这里错过了一些关于yield()vs的事fetch()吗?使用yield()和生成器有更多好处吗?
PS:在大型应用程序中编写干净,可读和可维护的代码yield()比使用它更容易fetch().
yield ×10
python ×4
generator ×3
java ×2
php ×2
c# ×1
decorator ×1
ecmascript-6 ×1
expression ×1
fetch ×1
iterator ×1
javascript ×1
list ×1
mysqli ×1
pdo ×1
python-3.x ×1
scala ×1
set ×1
yield-return ×1