如何在 MATLAB 中进行多重赋值?
Posted
技术标签:
【中文标题】如何在 MATLAB 中进行多重赋值?【英文标题】:How do I do multiple assignment in 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.
错误消息的原因。
【参考方案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
varargoutk = 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.
【讨论】:
以上是关于如何在 MATLAB 中进行多重赋值?的主要内容,如果未能解决你的问题,请参考以下文章