我有一个for循环来检查一系列条件.在每次迭代时,它应仅为其中一个条件产生输出.如果没有条件为真,则最终产量是默认值.在每块收益率之后我是否必须继续?
def function():
for ii in aa:
if condition1(ii):
yield something1
yield something2
yield something3
continue
if condition2(ii):
yield something4
continue
#default
yield something5
continue
Run Code Online (Sandbox Code Playgroud) 以下是将可迭代项目拆分为子列表的两个函数.我相信这种类型的任务是多次编程的.我使用它们来解析由repr('result','case',123,4.56)和('dump',..)等行组成的日志文件.
我想改变这些,以便它们将产生迭代器而不是列表.因为列表可能会变得非常大,但我可以根据前几个项目决定接受或跳过它.此外,如果iter版本可用,我想嵌套它们,但这些列表版本会通过复制部分浪费一些内存.
但是从可迭代源中获取多个生成器对我来说并不容易,所以我请求帮助.如果可能的话,我希望避免引入新课程.
另外,如果您对这个问题有更好的标题,请告诉我.
谢谢!
def cleave_by_mark (stream, key_fn, end_with_mark=False):
'''[f f t][t][f f] (true) [f f][t][t f f](false)'''
buf = []
for item in stream:
if key_fn(item):
if end_with_mark: buf.append(item)
if buf: yield buf
buf = []
if end_with_mark: continue
buf.append(item)
if buf: yield buf
def cleave_by_change (stream, key_fn):
'''[1 1 1][2 2][3][2 2 2 2]'''
prev = None
buf = []
for item in stream:
iden = key_fn(item)
if prev is None: prev = iden
if …Run Code Online (Sandbox Code Playgroud) 为了澄清术语,yield是线程放弃时间片的时间.我感兴趣的平台是POSIX线程,但我认为这个问题很普遍.
假设我有消费者/生产者模式.如果我想扼杀消费者或生产者,哪个更好用,睡觉还是产量?我最感兴趣的是使用这两种功能的效率.
除了yield在Ruby中使用迭代器之外,我还使用它将控制权简单地传递回调用者,然后在被调用的方法中恢复控制.我想在C#中做的事情是类似的.在测试类中,我想获取一个连接实例,创建另一个使用该连接的变量实例,然后将该变量传递给调用方法,以便可以进行调整.然后,我希望控制返回到被调用的方法,以便可以处理连接.我想我想要像Ruby一样的块/闭包.这是一般的想法:
private static MyThing getThing()
{
using (var connection = new Connection())
{
yield return new MyThing(connection);
}
}
[TestMethod]
public void MyTest1()
{
// call getThing(), use yielded MyThing, control returns to getThing()
// for disposal
}
[TestMethod]
public void MyTest2()
{
// call getThing(), use yielded MyThing, control returns to getThing()
// for disposal
}
...
Run Code Online (Sandbox Code Playgroud)
这在C#中不起作用; ReSharper告诉我,body getThing不能是迭代器块,因为MyThing它不是迭代器接口类型.这绝对是正确的,但我不想迭代一些列表.我猜我不应该使用,yield如果我不使用迭代器.任何想法,我怎样才能实现在C#此块/关闭的事情,所以我没有给缠上了我的代码MyTest1,MyTest2......与代码getThing()的身上?
我知道os.listdir,但据我所知,它将目录中的所有文件名都存入内存,然后返回列表.我想要的是一种产生文件名,处理它,然后产生下一个文件名的方法,而不是将它们全部读入内存.
有没有办法做到这一点?我担心文件名更改,添加新文件以及使用此类方法删除文件的情况.一些迭代器阻止您在迭代期间修改集合,主要是通过在开始时获取集合状态的快照,并在每个move操作上比较该状态.如果有一个迭代器能够从路径中产生文件名,那么如果有文件系统更改(添加,删除,重命名迭代目录中的文件)修改集合会引发错误吗?
可能有一些情况可能导致迭代器失败,这一切都取决于迭代器如何维持状态.使用S.Lotts示例:
filea.txt
fileb.txt
filec.txt
Run Code Online (Sandbox Code Playgroud)
迭代器产量filea.txt.期间processing,filea.txt被重命名为filey.txt和fileb.txt被重命名为filez.txt.当迭代器试图获取下一个文件时,如果要使用文件名filea.txt找到它的当前位置以便找到下一个文件filea.txt而不存在,会发生什么?它可能无法恢复它在集合中的位置.类似地,如果迭代器fileb.txt在屈服时要获取filea.txt,它可能会查找fileb.txt,失败并产生错误的位置.
如果迭代器能够以某种方式维护索引dir.get_file(0),那么维护位置状态不会受到影响,但是一些文件可能会被遗漏,因为它们的索引可以被移动到迭代器"后面"的索引.
这当然是理论上的,因为似乎没有内置(python)方法迭代目录中的文件.但是,下面有一些很好的答案可以通过使用队列和通知来解决问题.
编辑:
关注的操作系统是Redhat.我的用例是这样的:
进程A不断将文件写入存储位置.进程B(我正在写的那个)将迭代这些文件,根据文件名进行一些处理,并将文件移动到另一个位置.
编辑:
有效的定义:
形容词1.良好的基础或合理的,相关的.
(对不起S.Lott,我无法抗拒).
我已经编辑了上面的段落.
考虑以下程序(在CPython 3.4.0b1上运行):
import math
import asyncio
from asyncio import coroutine
@coroutine
def fast_sqrt(x):
future = asyncio.Future()
if x >= 0:
future.set_result(math.sqrt(x))
else:
future.set_exception(Exception("negative number"))
return future
def slow_sqrt(x):
yield from asyncio.sleep(1)
future = asyncio.Future()
if x >= 0:
future.set_result(math.sqrt(x))
else:
future.set_exception(Exception("negative number"))
return future
@coroutine
def run_test():
for x in [2, -2]:
for f in [fast_sqrt, slow_sqrt]:
try:
future = yield from f(x)
print("\n{} {}".format(future, type(future)))
res = future.result()
print("{} result: {}".format(f, res))
except Exception as e:
print("{} exception: {}".format(f, …Run Code Online (Sandbox Code Playgroud) 我asyncio.Protocol.data_received在新的Python asyncio模块的回调中执行异步操作时遇到问题.
考虑以下服务器:
class MathServer(asyncio.Protocol):
@asyncio.coroutine
def slow_sqrt(self, x):
yield from asyncio.sleep(1)
return math.sqrt(x)
def fast_sqrt(self, x):
return math.sqrt(x)
def connection_made(self, transport):
self.transport = transport
#@asyncio.coroutine
def data_received(self, data):
print('data received: {}'.format(data.decode()))
x = json.loads(data.decode())
#res = self.fast_sqrt(x)
res = yield from self.slow_sqrt(x)
self.transport.write(json.dumps(res).encode('utf8'))
self.transport.close()
Run Code Online (Sandbox Code Playgroud)
与以下客户一起使用:
class MathClient(asyncio.Protocol):
def connection_made(self, transport):
transport.write(json.dumps(2.).encode('utf8'))
def data_received(self, data):
print('data received: {}'.format(data.decode()))
def connection_lost(self, exc):
asyncio.get_event_loop().stop()
Run Code Online (Sandbox Code Playgroud)
随着self.fast_sqrt被召唤,一切都按预期工作.
有self.slow_sqrt,它不起作用.
它也不适用self.fast_sqrt于@asyncio.coroutine装饰器data_received.
我觉得我在这里缺少一些基本的东西.
完整的代码在这里: …
考虑以下C#程序:
using System;
using System.Linq;
using System.Collections.Generic;
public class Test
{
static IEnumerable<Action> Get()
{
for (int i = 0; i < 2; i++)
{
int capture = i;
yield return () => Console.WriteLine(capture.ToString());
}
}
public static void Main(string[] args)
{
foreach (var a in Get()) a();
foreach (var a in Get().ToList()) a();
}
}
Run Code Online (Sandbox Code Playgroud)
在Mono编译器下执行时(例如Mono 2.10.2.0 - 粘贴到此处),它会写入以下输出:
0
1
1
1
Run Code Online (Sandbox Code Playgroud)
这对我来说似乎完全不合逻辑.当直接迭代yield函数时,for循环的范围是"正确地"(根据我的理解)使用的.但是当我首先将结果存储在列表中时,范围始终是最后一个操作?!
我可以假设这是Mono编译器中的一个错误,还是我遇到了C#的lambda和yield-stuff的神秘角落?
顺便说一句:当使用Visual Studio编译器(以及MS.NET或单声道执行)时,结果是预期的 0 1 0 1
我有一个方法,它采用一个生成器加上一些额外的参数,并产生一个新的生成器:
function merge(\Generator $carry, array $additional)
{
foreach ( $carry as $item ) {
yield $item;
}
foreach ( $additional as $item ) {
yield $item;
}
}
Run Code Online (Sandbox Code Playgroud)
此函数的常用用例与此类似:
function source()
{
for ( $i = 0; $i < 3; $i++ ) {
yield $i;
}
}
foreach ( merge(source(), [4, 5]) as $item ) {
var_dump($item);
}
Run Code Online (Sandbox Code Playgroud)
但问题是有时我需要将空源传递给merge方法.理想情况下,我希望能够做到这样的事情:
merge(\Generator::getEmpty(), [4, 5]);
Run Code Online (Sandbox Code Playgroud)
这正是我在C#中所做的事情(有一个IEnumerable<T>.Empty属性).但我手册中没有看到任何类型的empty发电机.
我已经设法使用此函数解决此问题(现在):
function sourceEmpty()
{
if ( false ) { …Run Code Online (Sandbox Code Playgroud) 下面是scala中for/yield的标准格式:请注意它需要一个集合 - 其元素驱动迭代.
for (blah <- blahs) yield someThingDependentOnBlah
Run Code Online (Sandbox Code Playgroud)
我有一种情况,循环中会发生不确定的迭代次数.内循环逻辑确定将执行的数量.
while (condition) { some logic that affects the triggering condition } yield blah
Run Code Online (Sandbox Code Playgroud)
每次迭代都会生成一个序列的一个元素 - 就像编程产量一样.建议的方法是什么?