我需要生成多个结果,但是一次只生成一个,而不是在数组中一次性生成所有结果。
我应该如何在Matlab中使用类似Python的生成器语法实现这个功能?
我需要生成多个结果,但是一次只生成一个,而不是在数组中一次性生成所有结果。
我应该如何在Matlab中使用类似Python的生成器语法实现这个功能?
使用含有 yield
关键字的函数时,它们会返回一个生成器。生成器是迭代器的一种类型。虽然 MATLAB 不提供两者的语法,但您可以自己实现“迭代器接口”。下面是一个类似于 Python 中的 xrange
函数的示例:
classdef rangeIterator < handle
properties (Access = private)
i
n
end
methods
function obj = rangeIterator(n)
obj.i = 0;
obj.n = n;
end
function val = next(obj)
if obj.i < obj.n
val = obj.i;
obj.i = obj.i + 1;
else
error('Iterator:StopIteration', 'Stop iteration')
end
end
function reset(obj)
obj.i = 0;
end
end
end
这是我们如何使用迭代器:
r = rangeIterator(10);
try
% keep call next() method until it throws StopIteration
while true
x = r.next();
disp(x);
end
catch ME
% if it is not the "stop iteration" exception, rethrow it as an error
if ~strcmp(ME.identifier,'Iterator:StopIteration')
rethrow(ME);
end
end
请注意,在Python中使用迭代器时,使用for .. in ..
结构时,它内部会执行类似的操作。
您可以使用常规函数而不是类来编写类似的内容,通过使用persistent
变量或闭包来存储函数的本地状态,并在每次调用函数时返回“中间结果”。
size
(返回 [1,n]
)和 subsref
方法,甚至可以简单地保持正常的 for .. in ...
语法。 - sebastian在MATLAB中(在Octave中好像不行),你可以使用封闭函数(嵌套的作用域函数):
function iterator = MyTimeStampedValues(values)
index = 1;
function [value, timestamp, done] = next()
if index <= length(values)
value = values(index);
timestamp = datestr(now);
done = (index == length(values));
index = index + 1;
else
error('Values exhausted');
end
end
iterator = @next;
end
然后
iterator = MyTimeStampedValues([1 2 3 4 5]);
[v, ts, done] = iterator(); % [1, '13-Jan-2014 23:30:45', false]
[v, ts, done] = iterator(); % ...
values
是在调用MyTimeStampedValues
时构建的。因此,实际上并没有任何惰性评估。 - Lumen