【问题标题】:How do I do multiple assignment in MATLAB?如何在 MATLAB 中进行多重赋值?
【发布时间】:2011-01-21 04:22:30
【问题描述】:

这是我正在寻找的示例:

>> foo = [88, 12];
>> [x, y] = foo;

我会期待之后会发生这样的事情:

>> x

x =

    88

>> y

y =

    12

但我得到的错误如下:

??? Too many output arguments.

我认为deal() 可能会这样做,但它似乎只适用于单元格。

>> [x, y] = deal(foo{:});
??? Cell contents reference from a non-cell array object.

如何解决我的问题?如果我想分别处理它们,我必须不断地按 1 和 2 索引吗?

【问题讨论】:

  • 只有当 foo 是一个单元格时交易才有效。您已将 foo 定义为标准数组。这就是您收到 ??? Cell contents reference from a non-cell array object. 错误消息的原因。

标签: arrays matlab variables variable-assignment


【解决方案1】:

您根本不需要deal(编辑:对于Matlab 7.0 或更高版本),对于您的示例,您不需要mat2cell;您可以使用 num2cell 而不使用其他参数::

foo = [88, 12];
fooCell = num2cell(foo);
[x y]=fooCell{:}

x =

    88


y =

    12

如果您出于其他原因想使用deal,您可以:

foo = [88, 12];
fooCell = num2cell(foo);
[x y]=deal(fooCell{:})

x =

    88


y =

    12

【讨论】:

  • 只是一个旁注,我认为你只能在 Matlab 7+ 中不使用交易(如第一个示例)。
  • 有趣。我不知道现在这笔交易是不必要的。但是,我故意使用 mat2cell,因为我假设 OP 可能想要将列彼此分开。
  • 这真是太好了。但是有什么办法可以把所有东西都放在一条线上吗?可能是这样的:[x y] = num2cell(foo){:}(抱歉,Matlab 仍然经常混淆。)
  • @Justin:好点,您需要 7.0 (2004) 或更高版本。 @Jonas:是的,mat2cell 很好,如果你想以不同的方式分开。 @Benjamin:我不知道单行方法,除非您首先使用单元格;如果你从标量开始,你可以使用deal(88,12)。如果我们为许多 Matlab 命令提供类似 num2cell(foo){:} 的东西会很好。
【解决方案2】:

请注意,deal 接受“列表”作为参数,而不是元胞数组。因此,以下工作按预期工作:

> [x,y] = deal(88,12)
x = 88

y = 12

语法c{:} 将单元格数组转换为列表,列表是comma separated values,就像在函数参数中一样。这意味着您可以使用c{:} 语法作为deal 以外的其他函数的参数。要看到这一点,请尝试以下操作:

> z = plus(1,2)
z = 3

> c = {1,2};
> z = plus(c{:});
z = 3

【讨论】:

    【解决方案3】:

    要在一行中使用num2cell 解决方案,请定义一个辅助函数list

    function varargout = list(x)
    % return matrix elements as separate output arguments
    % example: [a1,a2,a3,a4] = list(1:4)
    
    varargout = num2cell(x);
    
    end
    

    【讨论】:

    • 示例[a1,a2,a3,a4] = list(1:4) 不会导致Too many output arguments 错误吗?
    【解决方案4】:

    mtrw 说了什么。基本上,您希望对元胞数组使用 deal(尽管 deal(88,12) 也可以)。

    假设您从一个 n×2 的数组 foo 开始,并且您想将第一列分配给 x,第二列分配给 y,请执行以下操作:

    foo = [88,12;89,13;90,14];
    %# divide the columns of foo into separate cells, i.e. do mat2cell(foo,3,[1,1])
    fooCell = mat2cell(foo,size(foo,1),ones(size(foo,2),1));
    [x,y] = deal(fooCell{:});
    

    【讨论】:

      【解决方案5】:

      DEAL 非常有用,但也非常令人困惑。我相信foo 本身需要是一个单元阵列。以下似乎适用于 Octave,如果我没记错的话,它也适用于 MATLAB:

      > foo = {88, 12}
      foo =
      
      {
        [1,1] =  88
        [1,2] =  12
      }
      
      > [x,y] = deal(foo{:})
      x =  88
      y =  12
      

      【讨论】:

        【解决方案6】:

        我无法评论其他答案,所以单独添加。

        you can use deal(88,12) if you are starting from scalars

        deal 也可以用作非标量的单线,当然,如果您已经将它们放在单独的变量中,例如:

        a = 123;
        b = rand(3);
        c = {a, b};
        d = struct('field','val')
        

        现在你用一行来处理它们:

        >> [x,y,z,w] = deal(a,b,c,d)
        x =
           123
        y =
            0.6370    0.2165    0.6711
            0.2945    0.8803    0.2705
            0.7633    0.1537    0.0767
        z = 
            [123]    [3x3 double]
        w = 
            field: 'val'
        

        但是,如果将它们打包在一个变量中,则只能在它们位于单元格或结构体数组中时使用deal - deal(X{:}) 用于单元格数组,deal(S.field) 用于结构体数组。 (在后一种情况下,只处理一个字段,但来自数组中的所有结构。)使用 Matlab v.7+,您可以在不使用 deal 的情况下使用 X{:}S.field,如其他答案中所述。

        【讨论】:

          【解决方案7】:

          为方便起见,创建一个函数 arr2vars

          function varargout = arr2vars(arr)
          % Distribute elements over variables
          
          N = numel(arr);
          if nargout ~= N
              error('Number of outputs does not match number of elements')
          end
          for k = 1:N
              varargout{k} = arr(k);
          end
          

          你可以像这样使用它

          [~,roi] = imcrop(im);
          [x,w,y,h] = arr2vars(roi);
          

          【讨论】:

            【解决方案8】:

            您可能正在寻找

            >>> foo = [88, 12];
            >>> [x, y] = deal(foo(1), foo(2))
            

            导致

            x = 
                88
            
            y = 
                12
            

            所以你有一个工作单线。

            【讨论】:

              【解决方案9】:

              有一个更简单的方法。

              x = foo (1, 1)  
              y = foo (1, 2)
              

              提供

              >> x
              
              x =
              
              88
              
              >> y
              
              y =
              
              12
              

              完整文档在Mathworks.

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2014-01-03
                • 1970-01-01
                • 2012-10-14
                • 1970-01-01
                • 2015-11-22
                • 2015-01-08
                相关资源
                最近更新 更多