什么是 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 中的行为是什么)。
在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 中的行为是什么)。