I need to generate multiple results but one at a time, as opposed to everything at once in an array.
How do I do that in Matlab with a generator like syntax as in Python?
When executing functions that use the yield
keyword, they actually return a generator. Generators are a type of iterators. While MATLAB does not provide the syntax for either, you can implement the "iterator interface" yourself. Here is an example similar to xrange
function in python:
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
Here is how we use the iterator:
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
Note the when using the construct for .. in ..
in Python on iterators, it internally does a similar thing.
You could write something similar using regular functions instead of classes, by using either persistent
variables or a closure to store the local state of the function, and return "intermediate results" each time it is called.
In MATLAB (not yet? in Octave), you can use closures (nested, scoped functions):
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
and then
iterator = MyTimeStampedValues([1 2 3 4 5]);
[v, ts, done] = iterator(); % [1, '13-Jan-2014 23:30:45', false]
[v, ts, done] = iterator(); % ...
来源:https://stackoverflow.com/questions/21099040/what-is-the-matlab-equivalent-of-the-yield-keyword-in-python