2014-01-13 58 views
5

我需要一次產生多個結果,但一次只能有一個結果,而不是一次一個數組。什麼是等效於Python的yield關鍵字的Matlab?

我該如何在Matlab中用像Python這樣的語法生成器來做到這一點?

+7

我不認爲Matlab具有懶惰的評價。 – senshin

+0

看看varargout,這可能會解決你的問題。 – Daniel

+2

如果內存不足,varargout將無法解決問題。 –

回答

10

執行使用yield關鍵字的函數時,它們實際上會返回一個生成器。生成器是一種迭代器。雖然MATLAB不提供任何語法,但您可以自己實現"iterator interface"。下面是類似蟒蛇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變量或閉包來存儲函數的本地狀態,並在每次調用時返回「中間結果」。 (?尚未在八度)

+0

加,被我的哭泣的兒子打斷了。我正在編寫一個解決方案,以便在構造函數中接受函數句柄。無論如何,+1 – Jonas

+0

如果你重載了'size'(在Iterator上正確地返回'[1,n]')和'subsref'方法,你甚至可以簡單地保持正常的'for ... in ...'語法。 – sebastian

2

在MATLAB中,你可以使用閉包(嵌套,範圍的功能):

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(); % ... 
+1

這在MATLAB R2013b中工作得很好,但'values'是在調用'MyTimeStampedValues'時構造的。所以,沒有任何懶惰的評價。 – Lumen

+0

@Lumen這不是數字,而是這個例子中懶惰地產生的時間戳。原則上,它在Python中的工作和產出只是它的一個捷徑。它所做的是實現在呼叫之間保持狀態的東西。 – Trilarion

相關問題