【问题标题】:two-dimensional python dict with shared memory具有共享内存的二维 python dict
【发布时间】:2016-11-08 00:13:08
【问题描述】:

我需要将数据从 csv 文件或 excel 表(带有行和列)加载到二维 python 字典中。例如,如果 Excel 工作表中的数据如下所示:

    name  age  gender location
1   Jim   18    male   China
2   Ross  18    male   China
3   Cara  19    female Japan
4   Ted   18    male   China

那么输出的python dict应该是这样的:

data = {
  1: {'name': 'Jim', 'age': 18, 'gender': 'male', 'location': 'China'},
  2: {'name': 'Ross', 'age': 18, 'gender': 'male', 'location': 'China'},
  3: {'name': 'Cara', 'age': 19, 'gender': 'female', 'location': 'Japan'},
  4: {'name': 'Ted', 'age': 18, 'gender': 'male', 'location': 'China'}
}

您可以看到这个二维字典中有很多重复的信息(对于真实数据,它具有相同的条件),所以我想出了一个使用共享内存开发新字典的想法。具体来说,在上面的示例中,我希望我的二维字典只在多行中保存一份{'age': 18, 'gender': 'male', 'location': 'China'} 的副本(这些行不需要相邻)。如果我们调用data[1]['age']data[2]['age'],它应该在同一个提取的小共享字典中进行查找。

我已经阅读了python dict的源代码,并且我知道python dict只保存指向键和值的指针(通常对于小的int和string对象,不同的指针可能指向同一个对象)。因此,当我的意思是我只想保存一份副本时,我的意思是一份指针副本。

关于如何设计这个字典的任何想法?非常感谢!!!

编辑

对不起,我忘了提。此二维字典中的数据将是只读的。

【问题讨论】:

  • 这听起来是个很糟糕的主意。如果你改变吉姆的位置,罗斯和泰德也会突然改变。
  • @Kelvin 对不起,我忘了提。此字典中的数据将只是只读的:)
  • 除非这些人之间存在内在的共享组件,否则听起来您想要的是compression algorithm。请注意,原则上,这会使访问字典中的项目变慢——空间与速度的权衡。
  • @Kelvin 是的,这是真的。我的意图确实是压缩数据。我现在的想法是将指向提取的共享字典的多个指针添加到第二级字典中。如果查找未能在其原始 ma_table 中找到键,它将在其相关的共享字典中查找键。虽然它会增加查找时间,但也许我会节省一堆内存。
  • 如果数据是短字符串,无论如何都会被实习,因此每个dict中具有相同字符串的开销将自动降低。

标签: python dictionary python-extensions


【解决方案1】:

我猜你问的是数据压缩解决方案,它应该同时考虑内存大小和引用的使用。最小的内存占用通常属于一个整数,它至少应该和内存引用一样小,所以我会尝试将所有内容映射到整数,除非它太不方便。此外,列表比字典小,允许直接快速索引。

这是一个替代实现,可能会激发一些想法:

import sys

data = {
  1: {'name': 'Jim', 'age': 18, 'gender': 'male', 'location': 'China'},
  2: {'name': 'Ross', 'age': 18, 'gender': 'male', 'location': 'China'},
  3: {'name': 'Cara', 'age': 19, 'gender': 'female', 'location': 'Japan'},
  4: {'name': 'Ted', 'age': 18, 'gender': 'male', 'location': 'China'}
}

In [43]: sys.getsizeof(data)
Out[43]: 280    # bytes

data_list = [ 
  ('Jim', 18, 0, 'CH'),     # 'CH' => 'China'
  ('Ross', 18, 0, 'CH'),    #  0 => Female, 1 => Male
  ('Cara', 19, 1, 'JP'),    # 'JP' => 'Japan'
  ('Ted', 18, 0, 'CH')
]


In [44]: sys.getsizeof(data_list)
Out[44]: 104   # bytes

_name, _age, _gender, _location = 0, 1, 2, 3

In [45]: data_list[2][_age]  # access as 2D array instead of 2-level dict
Out[45]: 19

上面的解决方案会慢一些,但对大字符串有一些好处。除非每条记录开始变长,否则使用引用可能不会为您节省任何东西。最后,如果您将所有值替换为整数而不是字符串名称和国家代码,您将使用 Python 列表进行大量压缩。

如果您真的想选择能够提供最佳压缩的数字代码,请查看 Huffman Coding,例如此站点:http://www.geeksforgeeks.org/greedy-algorithms-set-3-huffman-coding

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-20
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-13
    相关资源
    最近更新 更多