【问题标题】:Is there generator/iterator like that in python for map keys in matlab to save memory?在 python 中是否有类似的生成器/迭代器用于 matlab 中的映射键以节省内存?
【发布时间】:2018-12-23 07:25:48
【问题描述】:

我在 matlab 中有一个大地图,想遍历它的所有键。 但是我只能先为键存储一个单元格并遍历该单元格,这需要内存来存储所有键。 而在python中,生成器/迭代器可以在循环中顺序返回列表的索引或条目,这不会占用太多内存。

ma​​tlab中,我尝试了for循环:

% Let MAP is a containers.Map with 10000000 keys.
keys = MAP.keys;
for keyIdx = 1:size(keys,2)
    MAP(keys{1,keyIdx});
end

python 中,for 循环与迭代器:

% Let MAP is a dictionary with 10000000 keys.
for key in MAP.iterkeys():
    MAP[key]

那么,当我处理地图时,matlab 中的 python 中是否有类似的生成器/迭代器来节省内存?

【问题讨论】:

  • 这在纯 MATLAB 中不存在。但正如question 中所述,您可以自己实现它
  • 请注意,MATLAB 使用惰性复制,这意味着,只要您不修改 keys,它将指向存储映射中键的同一内存。除非内存不足,否则不要担心 MATLAB 的内存使用情况! :)
  • Thank you@CrisLuengo.keys = MAP.keys 实际上会消耗内存来存储cell ,而我无法直接使用MAP.keys(idx)MAP.keys{idx} 遍历键.
  • 我没有收到您的评论通知,请确保@之前有一个空格!
  • 我说的是keys = MAP.keys 不会占用任何额外的内存,因为单元格数组keys 将指向与存储在MAP 中的键相同的内存.在您尝试修改副本之前,MATLAB 不会复制数据。

标签: matlab dictionary memory-management iterator key


【解决方案1】:

回答您的主要问题:不。MATLAB 中没有生成器。 此外,您编写的 Python 代码不使用 Python 生成器。 两个 sn-ps 的内存占用是相似的。 但是我想我没有得到有关您问题的详细信息....

最后:

  • 您可以使用numel(keys) 代替size(keys, 2),因为keys 是一维的
  • 您可以使用MAP(keys{keyIdx}) 代替MAP(keys{1, keyIdx})

【讨论】:

  • 谢谢! .iterkeys() 是 python 中字典的生成器方法,其中一个键在循环中返回一次,因此 python 中的生成器可以避免像 matlab 中那样花费内存来存储 MAP 的整个键单元。我错了吗?我无法理解您的'两个 sn-ps 的内存占用相似'
  • 那是发电机吗?我想念yield 语法。我认为“一次一个元素”功能用于为 value 中存储的内容节省内存
  • 是的。在 python 中,.values() 返回一个字典的所有值的列表,而.itervalues() 是一个迭代器(对不起,我混合了iteratorgenerator,并从Difference between Python's Generators and Iterators 学习),所以.keys() 和@987654335 @.
  • 那么,我没有办法避免在matlab中存储MAP的巨大关键单元格吗?或者还有其他方法可以遍历matlab中map的所有key-value吗?
【解决方案2】:

MATLAB 使用惰性复制或写时复制机制。这意味着当你这样做时

B = A;

AB 都指向同一个内存,直到您尝试修改其中一个数组,此时 MATLAB 将复制数据,以便修改一个不会影响另一个副本。

这也意味着,给定一个Containers.Map 对象map

keys = map.keys

不会复制密钥,而是keys 将与密钥共享数据,因为它们存储在地图中。


注意

keys = map.keys;
for keyIdx = 1:numel(keys)
   value = map(keys{keyIdx})
end

相同
for key = map.keys
   value = map(key{1})
end

和一样

for value = map.values
   value = value{1}
end

在这些情况下都不会复制数据!

(我在猜测语法,因为我现在正在手机上打字,我认为这里需要 {1} 索引,但我可能错了。)

【讨论】:

  • 非常感谢! {1} 是对的。我完全明白你的想法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-01
  • 2017-09-20
  • 1970-01-01
  • 2014-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多