如何制作改变文件的生成器.
我试图让它在文件中找到一个模式,并将内容添加到它下面的行.
我正在寻找一种迭代迭代迭代的第一n项的pythonic方法(upd:在常见情况下不是列表,因为列表事情是微不足道的),并且尽可能快地执行此操作非常重要.这是我现在这样做的方式:
count = 0
for item in iterable:
do_something(item)
count += 1
if count >= n: break
Run Code Online (Sandbox Code Playgroud)
对我来说似乎并不整洁.另一种方法是:
for item in itertools.islice(iterable, n):
do_something(item)
Run Code Online (Sandbox Code Playgroud)
这看起来不错,问题是它是否足够快与一些发电机一起使用?例如:
pair_generator = lambda iterable: itertools.izip(*[iter(iterable)]*2)
for item in itertools.islice(pair_generator(iterable), n):
so_something(item)
Run Code Online (Sandbox Code Playgroud)
与第一种方法相比,它运行得足够快吗?有没有更简单的方法呢?
我写了自己的发电机,从这个发射的控制台开始
rails generate ead_document TechnicalOpinion --document_type_id=1
Run Code Online (Sandbox Code Playgroud)
它创建模型和迁移.我想从我的控制器执行生成器而不使用ruby系统命令.有没有办法做到这一点?
每当我生成一个脚手架时,Rspec生成器总会创建如下所示的规范:
invoke rspec
create spec/controllers/stars_controller_spec.rb
invoke helper
create spec/routing/stars_routing_spec.rb
invoke rspec
create spec/requests/stars_spec.rb
Run Code Online (Sandbox Code Playgroud)
如何确保永远不会生成这些?我尝试像这样设置配置设置,但它没有帮助:
config.generators do |g|
g.test_framework :rspec, :fixture => true, :views => false
g.view_specs false
g.integration_specs false
g.helper_specs false
end
Run Code Online (Sandbox Code Playgroud) 在Python中,大多数收益率的例子都说明了这一点
yield from foo()
Run Code Online (Sandbox Code Playgroud)
类似于
for x in foo(): yield x
Run Code Online (Sandbox Code Playgroud)
另一方面它似乎并不完全相同,并且有一些魔法投入.我觉得使用一个我不理解的魔法函数有点不安.我有什么必须知道的,yield from以避免陷入魔法做我不期望的事情的魔力?我应该注意到魔法提供了哪些优势?
我正在尝试将一些结果写入pickle文件,如下所示:
raw_X = (self.token_ques(text) for text in training_data)
with open('/root/Desktop/classifier_result.pkl', 'wb') as handle:
pickle.dump(raw_X, handle)
Run Code Online (Sandbox Code Playgroud)
错误:
raise TypeError, "can't pickle %s objects" % base.__name__
TypeError: can't pickle generator objects
Run Code Online (Sandbox Code Playgroud)
任何帮助都会非常明显.
有没有更好的方法,而不是使用生成器函数作为闭包添加数组的值?
var sumArrays = function(){
var sum = 0;
return function*(){
while(true){
var array = yield sum;
if(array.__proto__.constructor === Array){
sum += array.reduce(function(val,val2){ return val+val2; });
}
else sum=0;
}
};
};
var gen = sumArrays();
// is this step required to make a generator or could it be done at least differently to spare yourself from doing this step?
gen = gen();
// sum some values of arrays up
console.log('sum: ',gen.next()); // Object { value=0, done=false}
console.log('sum: ',gen.next([1,2,3,4])); // …Run Code Online (Sandbox Code Playgroud) 我正在尝试将此Python2.7代码重写为新的异步世界顺序:
def get_api_results(func, iterable):
pool = multiprocessing.Pool(5)
for res in pool.map(func, iterable):
yield res
Run Code Online (Sandbox Code Playgroud)
map()阻塞直到计算完所有结果,所以我试图将其重写为异步实现,一旦准备就会产生结果.同样map(),返回值必须按照与之相同的顺序返回iterable.我试过这个(我需要requests因为传统的身份验证要求):
import requests
def get(i):
r = requests.get('https://example.com/api/items/%s' % i)
return i, r.json()
async def get_api_results():
loop = asyncio.get_event_loop()
futures = []
for n in range(1, 11):
futures.append(loop.run_in_executor(None, get, n))
async for f in futures:
k, v = await f
yield k, v
for r in get_api_results():
print(r)
Run Code Online (Sandbox Code Playgroud)
但是使用Python 3.6我得到了:
File "scratch.py", line 16, in <module>
for r in …Run Code Online (Sandbox Code Playgroud) tf.data 有一个from_generator初始值设定项,它似乎不可扩展。来自官方指南
注意:虽然这是一种方便的方法,但它的可移植性和可扩展性有限。它必须在创建生成器的同一个 python 进程中运行,并且仍然受 Python GIL 的约束。
https://www.tensorflow.org/guide/data#sumption_python_generators
并在官方文档中
注意:Dataset.from_generator() 的当前实现使用 tf.numpy_function 并继承相同的约束。特别是,它需要将与 Dataset 和 Iterator 相关的操作放置在与调用 Dataset.from_generator() 的 Python 程序相同的进程中的设备上。生成器的主体不会在 GraphDef 中序列化,如果您需要序列化模型并在不同的环境中恢复它,则不应使用此方法。
注意:如果生成器依赖于可变全局变量或其他外部状态,请注意运行时可能会多次调用生成器(以支持重复数据集)以及在调用 Dataset.from_generator() 和产生生成器的第一个元素。改变全局变量或外部状态可能会导致未定义的行为,我们建议您在调用 Dataset.from_generator() 之前在生成器中显式缓存任何外部状态。
https://www.tensorflow.org/api_docs/python/tf/data/Dataset#from_generator
然而,生成器是训练非常大量数据的一种相当常见的方法。所以必须有一些替代的最佳实践,但官方的 Tensorflow 数据指南没有提供任何信息。
更新:我已经启动了一个关于 python-ideas的线程来为此目的提出额外的语法或 stdlib 函数(即指定由 发送的第一个值yield from)。到目前为止 0 回复...:/
如何拦截子生成器的第一个生成值,但使用 将迭代的其余部分委托给后者yield from?
例如,假设我们有一个任意的双向生成器subgen,我们想将它包装在另一个生成器中gen。的目的gen是拦截第一个subgen生成的值,并将生成的其余部分(包括发送的值、抛出的异常、.close() 等)委托给子生成器。
可能会想到的第一件事可能是这样的:
def gen():
g = subgen()
first = next(g)
# do something with first...
yield "intercepted"
# delegate the rest
yield from g
Run Code Online (Sandbox Code Playgroud)
但这是错误的,因为当调用者.send在获得第一个值后将某些东西返回给生成器时,它最终会作为yield "intercepted"表达式的值被忽略,而是作为第一个值g接收,作为语义的一部分的。None.sendyield from
所以我们可能会想这样做:
def gen():
g = subgen()
first = next(g)
# do …Run Code Online (Sandbox Code Playgroud) generator ×10
python ×6
yield-from ×2
async-await ×1
asynchronous ×1
iterator ×1
javascript ×1
keras ×1
performance ×1
pickle ×1
python-3.x ×1
rspec ×1
tensorflow ×1
tf.keras ×1
yield ×1