在Python中使用dicts作为集合中的项目

Chr*_*row 4 python dictionary set

有没有办法通过使用一个简单的方法,如比较器函数将一些dict对象放入Python的集合中?

在这里遇到了一些涉及大量看起来非常复杂且容易出错的问题的解决方案(似乎是在未定义的订单中迭代dict的问题等等).很高兴做这样的技术在数学上不具有数学效果的东西,因为两个对象可以有不同的信息,但被评估为相同,但对于大量现实生活中的用例非常有用:

# One of the dicts:
widget = {
     lunch:  'eggs',
     dunner: 'steak'
}

# Define a comparator function (ignores dinner)
def comparator(widget1, widget2):
     return widget1['lunch'] > widget2['lunch']

widget_set = set([widget], comparator)
Run Code Online (Sandbox Code Playgroud)

Mar*_*ers 6

你不能.您只能将不可变值放入集合中.这种限制不仅仅是能够比较价值; 你需要测试两者是否相等并且能够获得哈希值,并且大部分值必须保持稳定.最后一个要求的可变值失败.

通过将字典转换为一系列键值元组,可以使字典不可变; 如果值也是不可变的,则以下工作:

widget_set = {tuple(sorted(widget.items()))}  # {..} is a set literal, Python 2.7 and newer
Run Code Online (Sandbox Code Playgroud)

这使得可以通过tuple(sorted(somedict.items())) in widget_set至少测试来测试相同字典的存在.将值重新变为a dict是一个要求dict它的问题:

dict(widget_set.pop())
Run Code Online (Sandbox Code Playgroud)

演示:

>>> widget = {
...      'lunch':  'eggs',
...      'dunner': 'steak'
... }
>>> widget_set = {tuple(sorted(widget.items()))}
>>> tuple(sorted(widget.items())) in widget_set
True
>>> dict(widget_set.pop())
{'lunch': 'eggs', 'dunner': 'steak'}
Run Code Online (Sandbox Code Playgroud)