【问题标题】:Python: Compare dict with a static reference?Python:将 dict 与静态引用进行比较?
【发布时间】:2010-09-30 20:26:44
【问题描述】:

我必须检查字典是否和昨天一样,如果它发生了变化。

在 PHP 中,我可以序列化一个数组并比较昨天和今天的结果字符串。但是,我不知道如何在 Py.我读过一些关于 Pickle 的文章,也许它可以用 md5 以某种方式完成?

所以基本上我需要一种方法将 dict 分解为可比较的、可存储的值,该值不是文件,并且可以硬编码到 .py 文件中。

谢谢, A.R.

【问题讨论】:

  • “不是文件的可存储值”?什么?如果它是可存储的,它就是一个文件。你要什么?
  • 可存储,可以硬编码到脚本文件中,作为字符串。
  • 感谢那些回答的人。我现在有 3 个不同的好主意来说明如何做到这一点。明天会尝试并更新此条目。
  • 所以“不是文件的可存储值”意味着什么?这意味着“值的 Python 源表示”?这是你要求的吗?用 Python 表示法的东西?请更新问题以修正措辞,使其非常清楚。

标签: python google-app-engine dictionary compare


【解决方案1】:

字典的问题在于它们未定义的顺序。你必须确保你总是得到相同的字典结果(如果你想将它们作为字符串进行比较)。

您可以通过多种方式做到这一点:

1) Python 哈希(仅用于检查相等性;哈希实现可能特定于 Python 版本!)

print hash(str(sorted({1 : 2, 3 : 4}.items())))

2) MD5(最好只检查相等性)

import hashlib
print hashlib.md5(str(sorted({1 : 2, 3 : 4}.items()))).hexdigest()

3) 酸洗(序列化)

import pickle
serializedString = pickle.dumps({1 : 2, 3 : 4})

pickle 模块有不同的协议(我认为它不会对字典项进行排序),所以你不能进行字符串比较。您必须将数据解压到字典中,然后直接比较新旧字典 (d = pickle.loads(serializedString))。

4) 项元组表示(序列化)

根据您的评论,您需要可嵌入到 Python 源代码中的内容。正如 S.Lott 建议的那样,您可以使用 someDictionary.items() 的对象表示,它是一个包含所有(键、值)组合的列表作为元组(很可能是未排序的):

>>> repr({1 : 2, 3 : 4}.items())
'[(1, 2), (3, 4)]'

如果您希望将对象序列化为字符串,可以将此表示复制并粘贴到源代码中。

【讨论】:

  • (#4)有什么问题创建一个dictionary.items()的元组?
  • @S.Lott:问题是“可存储的值”,所以我认为 OP 希望将 dict 序列化为字符串。创建 d.items() 的排序元组仍然需要序列化 ​​- 但这隐藏在我的选项 #1 中。
  • @AndiDog:哈希是酸洗的补充。你可以两者都做,独立。事实上,人们经常两者兼而有之。他们序列化,然后散列序列化结果以简化更改检测。您只提供一种序列化技术和两种散列技术。为什么不添加其他序列化技术?
  • @S.Lott:JSON 已经被命名(尽管它不在标准库中),str(d.items()) 在我的回答中。您希望我添加哪种序列化技术?
  • @AndiDog:我会重复我之前的评论:dictionary.items()
【解决方案2】:

您可以使用 JSON 来获取您所要求的内容。

from django.utils import simplejson as json

dict_1 = {'a': 1, 'b': 2, 'c': 3}
dict_2 = {'a': 2, 'b': 7, 'd': 9}

dict_1_str = json.dumps(dict_1, sort_keys=True)
dict_2_str = json.dumps(dict_2, sort_keys=True)

if dict_1_str == dict_2_str:
   # do something with the new dict...
   pass

dict_X_str 变量将包含字典的序列化版本。您可以将其存储在 memcahce 或数据存储中以供以后比较。

【讨论】:

    【解决方案3】:

    pickle 绝对是您想要的。

    【讨论】:

      【解决方案4】:
      pickle.dumps(set(yourdict.items()))
      

      【讨论】:

      • 为什么要先转成set?
      • 经过测试,我发现不是严格需要的,因为 dicts 是可比的,而且 pickle 似乎强制执行键顺序。尽管如此,理论上不同的实现可以为相同的字典创建不同的序列化。相比之下,可比性是人生的既定目标,所以我觉得它“更安全”
      【解决方案5】:

      通过使用 pickle,您可以创建一个新的 DictProperty,允许您将 dict 放入数据存储区并稍后检索它以进行比较。

      这是一种实现方式:Can I store a python dictionary in google's BigTable datastore without serializing it explicitly?

      【讨论】:

        【解决方案6】:

        如果你这样做,你会得到一个一致且可比较的对象。它具有定义明确且可预测的顺序。您可以使用 difflib 来查找差异。此外,您可以轻松地从中重建高性能字典。

        static = list(sorted(some_dict.items()))
        
        a_dict= dict( static )
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多