什么是 MATLAB 等同于 Python 中的字典列表?

What is the MATLAB equivalent to a list of dicts in Python?

在Python中:

my_list = []
my_dict_a = {1: 'one'}
my_dict_b = {2: 'two'}
my_dict_c = {3: 'three'}
my_list.append(my_dict_a)
my_list.append(my_dict_b)
my_list.append(my_dict_c)

其中 my_list 现在等于 [{1: 'one'}, {2: 'two'}, {3: 'three'}]

如果我们可以说 containers.Map 是 python dict 的基本等价物,那么 MATLAB 等价于上面的 python append 是什么?

我在 MATLAB 中尝试过的:

知道:

>a=[];
>b=1;    
>a = [a, b]

a =  1

>a = [a, b]

a = 1     1

>a = [a, b]

a = 1     1     1

>a={};
>b=1;
>a=[a,b]

a = [1]

>a=[a,b]

a = [1]    [1]

>a=[a,b]

a = [1]    [1]    [1]

>a = [a; b]

a = 1

>a = [a; b]

a = 1
    1

>a = [a; b]

a =
     1
     1
     1

然而,当我尝试对 containers.Map 对象执行相同操作时:

>dictA=containers.Map();
>dictA('first')=1;
>dictA('second')=2;
>dictA('third')=3;

>a=[];
>a = [a, dictA]

a = 

  Map with properties:

        Count: 3
      KeyType: char
    ValueType: any

>a = [a, dictA]
Error using containers.Map/horzcat
Horizontal concatenation is not supported by a containers.Map.

好的。但是:

>a=[];
>a = [a; dictA]

a = 

  Map with properties:

        Count: 3
      KeyType: char
    ValueType: any

>a = [a; dictA]

a = 

  Map with properties:

        Count: 3
      KeyType: char
    ValueType: any

>whos a
  Name      Size            Bytes  Class             Attributes

  a         3x1               112  containers.Map

但它并没有继续追加:

>a={};
>a = [a; dictA]

a = 

  Map with properties:

        Count: 3
      KeyType: char
    ValueType: any

>a = [a; dictA]

a = 

  Map with properties:

        Count: 3
      KeyType: char
    ValueType: any

>whos a
  Name      Size            Bytes  Class             Attributes

  a         3x1               112  containers.Map     

还有

>{dictA}

ans = 

    [3x1 containers.Map]


>a = {};
>a = [{a}; {dictA}]

a = 

    {}
    [3x1 containers.Map]

>a = [{a}; {dictA}]

a = 

    {2x1 cell          }
    [3x1 containers.Map]

>whos a
  Name      Size            Bytes  Class    Attributes

  a         2x1               672  cell               

>a = [{a}; {dictA}]

a = 

    {2x1 cell          }
    [3x1 containers.Map]

>whos a
  Name      Size            Bytes  Class    Attributes

  a         2x1              1008  cell       

>a = {};
>a = {a dictA}

a = 

    {}    [3x1 containers.Map]

>whos a
  Name      Size            Bytes  Class    Attributes

  a         1x2               336  cell               

a = {a dictA}

a = 

    {1x2 cell}    [3x1 containers.Map]

>whos a
  Name      Size            Bytes  Class    Attributes

  a         1x2               672  cell 

最后

>a = {};
>a = {[a] [dictA]}

a = 

    {}    [3x1 containers.Map]

>a = {[a] [dictA]}

a = 

    {1x2 cell}    [3x1 containers.Map]

>a = {[a] [dictA]}

a = 

    {1x2 cell}    [3x1 containers.Map]

可能的等效项是包含结构的单元格:

octave:52> d1.val='one';d2.val='two';d3.val='three';
octave:53> c={d1,d2,d3};
octave:54> c
c = 
{
  [1,1] =
    scalar structure containing the fields:
      val = one
  [1,2] =
    scalar structure containing the fields:
      val = two
  [1,3] =
    scalar structure containing the fields:
      val = three
}
octave:55> c{2}.val
ans = two

单元格具有列表的内容灵活性。结构就像一本字典,但对键有更多限制。或者您可以将它们比作 Python 对象。事实上,MATLAB 中最初的 'object' 实现是建立在结构之上的(在 1990 年代后期)。

另一种可能是结构数组。来自 Octave 文档:

 x(1).a = "string1";
 x(2).a = "string2";
 x(1).b = 1;
 x(2).b = 2;

octave:65> x
x =
  1x2 struct array containing the fields:
    a
    b
octave:66> x(1)
ans =
  scalar structure containing the fields:
    a = string1
    b =  1

有时使用 scipy.io.loadmat/savemat 在 MATLAB 和 numpy 之间来回写入对象会有所帮助。那些开发人员已经制定出一组等价物。


比较结构和容器的其他 SO 问题:

Hash tables in MATLAB

MATLAB 文档说容器最有效地保存小值 - 标量 (?) 和字符串。我还没有看到在单元格中收集容器的讨论。

如果您对 numpy/MATLAB 数据交换集合感兴趣,可能仍然是个问题 - 取决于它如何将它们保存到 .mat 文件。

containers.Map class 不支持与数值数组相同的数组连接(部分原因是 Map class 重载了一些数组访问函数)。所以你不能制作一个 Map 对象的数组(尽管当你尝试垂直连接时没有错误消息)。

containers.Map 个对象的元胞数组

但是,您可以制作 Map 个对象的元胞数组;您只需要注意语法即可。你已经很接近了,但我认为这就是你想要的:

>> a = {};
>> a = [a, {dictA}]
a = 
    [3x1 containers.Map]

>> a = [a, {dictA}]
a = 
    [3x1 containers.Map]    [3x1 containers.Map]

>> a = [a, {dictA}]
a = 
    [3x1 containers.Map]    [3x1 containers.Map]    [3x1 containers.Map]

>> a{1}('first')
ans =
     1

我们本可以使用分号来垂直连接它们 a = [a; {dictA}]

元胞数组,{},和[]

我的想法是 {} 用于将东西放入单元格(以及将它们取出),而 [] 是也适用于单元格的串联操作数组。

a = {}a 指定为空元胞数组。

a = [a, {dictA}]dictA 放入一个单元格中,然后将此 1x1 单元格数组与单元格数组 a.

连接起来

a = [{a}, {dictA}] 会把 a 放在另一个元胞数组中,导致你 运行 进入的怪异嵌套元胞数组。

a{1} returns 元胞数组 a 中第一个元胞的内容,在本例中是 Map 对象。

在我看来,元胞数组和各种brackets/parentheses的使用是学习 MATLAB 时最令人困惑的事情之一。

小心!这些是浅拷贝

请注意,这就是 MATLAB 所谓的“句柄 class”,这意味着 a{1}a{2}dictA 都是 pointers/references同一个对象。因此:

>> a{1}('fourth') = 4;
>> a
a = 
    [4x1 containers.Map]    [4x1 containers.Map]    [4x1 containers.Map]

请注意,这 3 个都变大了。只是想警告你,以防这与 Python 中的行为不同(我不知道 Python 中的行为是什么)。