【问题标题】:What is the Matlab equivalent of the yield keyword in Python?什么是 Python 中的 yield 关键字的 Matlab 等效项?
【发布时间】:2023-03-12 06:48:01
【问题描述】:

我需要一次生成多个结果,而不是一次在数组中生成所有结果。

如何在 Matlab 中使用类似于 Python 中的语法生成器来做到这一点?

【问题讨论】:

  • 我认为 Matlab 没有惰性求值。
  • 看看varargout,这可能会解决你的问题。
  • 如果是内存不足,varargout 解决不了问题。
  • 部分相关参考:CoroutineGeneratorIteratorLazy evaluation

标签: python matlab generator yield yield-keyword


【解决方案1】:

在执行使用yield 关键字的函数时,它们实际上会返回一个生成器。生成器是一种迭代器。虽然 MATLAB 不提供两者的语法,但您可以自己实现 "iterator interface"。下面是一个类似于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 变量或闭包来存储函数的本地状态,并在每次调用时返回“中间结果”。

【讨论】:

  • 嘎,被我哭闹的儿子打断了。我正在编写一个在构造函数中也可以接受函数句柄的解决方案。无论如何,+1
  • 如果你在迭代器上适当地重载size(返回[1,n])和subsref方法,你甚至可以简单地保持正常的for .. in ...语法。
【解决方案2】:

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

【讨论】:

  • 这在 MATLAB R2013b 中运行良好,但在调用 MyTimeStampedValues 时会构造 values。所以,真的没有任何懒惰的评估。
  • @Lumen 这不是数字,而是在此示例中延迟生成的时间戳。原则上它可以完成这项工作,Python 中的 yield 只是它的一个捷径。它所做的是实现在调用之间保持状态的东西。
猜你喜欢
  • 2011-01-17
  • 2010-12-29
  • 2011-03-11
  • 1970-01-01
  • 1970-01-01
  • 2010-12-31
  • 2014-09-27
相关资源
最近更新 更多