仅存储更改的Python字典

前端之家收集整理的这篇文章主要介绍了仅存储更改的Python字典前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我使用Inspyred库编写了一个用于设计优化的代码及其遗传算法的实现.本质上,优化过程在单个数据结构上创建了大量变体,在我的例子中,这是一个嵌套字典.

为了减少进程中使用的内存量,我一直在尝试创建某种差异字典类型,它只存储与基本字典不同的项目.其原因在于,在典型情况下,数据结构中95%的数据不会在任何变体中被修改,但数据结构的任何部分都可以包含变体.因此,出于灵活性的原因,我希望数据类型的行为或多或少像字典,但只存储更改.

这是我试图创建这个的结果:

  1. #!/usr/bin/python
  2. import unittest
  3. import copy
  4. global_base={}
  5. class DifferentialDict(object):
  6. """
  7. dictionary with differential storage of changes
  8. all DifferentialDict objects have the same base dictionary
  9. """
  10. def __init__(self,base=None):
  11. global global_base
  12. self.changes={}
  13. if not base==None:
  14. self.set_base(base)
  15. def set_base(self,base):
  16. global global_base
  17. global_base=copy.deepcopy(base)
  18. def __copy__(self):
  19. return self
  20. def __deepcopy__(self):
  21. new=DifferentialDict()
  22. new.changes=copy.deepcopy(self.changes)
  23. return new
  24. def get(self):
  25. global global_base
  26. outdict=copy.deepcopy(global_base)
  27. for key in self.changes:
  28. outdict[key]=self.changes[key]
  29. return outdict
  30. def __setitem__(self,key,value):
  31. self.changes[key]=value
  32. def __getitem__(self,key):
  33. global global_base
  34. if key in self.changes:
  35. return self.changes[key]
  36. else:
  37. return global_base[key]
  38. class TestDifferentialDict(unittest.TestCase):
  39. def test1(self):
  40. ldict={'a':{1:2,3:4},'b':{'c':[1,2,3],'d':'abc'}}
  41. ddict=DifferentialDict(base=ldict)
  42. self.assertEqual(ddict['a'],{1:2,3:4})
  43. ddict['a']=5
  44. self.assertEqual(ddict['a'],5)
  45. def test2(self):
  46. ldict={'a':{1:2,'d':'abc'}}
  47. ddict1=DifferentialDict(base=ldict)
  48. ddict2=DifferentialDict(base=ldict)
  49. ddict1['a'][3]=5
  50. ddict2['a'][3]=7
  51. self.assertEqual(ddict1['a'][3],5)
  52. self.assertEqual(ddict2['a'][3],7)
  53. def test3(self):
  54. ldict={'a':{1:2,'d':'abc'}}
  55. ddict1=DifferentialDict(base=ldict)
  56. ddict2=ddict1.__deepcopy__()
  57. ddict1['a'][3]=5
  58. ddict2['a'][3]=7
  59. self.assertEqual(ddict1['a'][3],7)
  60. if __name__ == "__main__":
  61. unittest.main()

它适用于简单的字典,但是当新字典嵌套在主字典中时会出现故障.我知道这是因为这些二级字典是真正的Python字典而不是我的DifferentialDict的实例化,导致覆盖global_base中的条目而不是self.changes中的更改.但是,它们必须是因为所有DifferentialDict实例共享相同的基本字典.我可以为每个DifferentialDict实例添加一个“入门级”键,但我的感觉是有一个更优雅的解决方案,这让我望而却步.

我真的很感激有关如何在嵌套时使我的差异字典工作的任何建议.提前致谢!

最佳答案
我现在没有时间尝试这个(可能稍后),但这里有两个观察结果:

综合指数

如果你使用元组作为索引,例如像这个dict [(5,3,2)]你就不会有这个问题.如果你的基础词典或差异词语都基于此,你就可以避免这个问题.

也许你甚至可以编写一些重写dict [a] [b] [c]到dict [(a,b,c)]的类来使这个内部变化透明化.

全球基地

我不明白为什么你使用全球基础.从我的角度来看,这使得代码更加复杂而不添加任何东西.为什么不直接存储基数:

  1. def MyDict(collections.abc.MutableSequence):
  2. def __init__(self,base):
  3. self._base = base
  4. my_global_base = dict()
  5. d = MyDict(my_global_base)
  6. d[2] = 'abc' # modifies self._base inside of the instance too,because it is the
  7. # same object

如果要更改基础的所有内容,只需使用popitem()删除所有项目,然后使用update()添加新项目.这样,由于全局变量,您的代码更灵活,并且没有任何令人惊讶的行为.

抽象基类

当重新实现序列,字典等类时,使用Python提供的abstract base classes可能会派上用场,它们可以为您完成一些实现工作.

猜你在找的Python相关文章