【发布时间】:2010-12-29 18:25:27
【问题描述】:
我的意思是为什么我们不能把 dict 的键作为 dict?
这意味着我们不能将字典作为另一个字典的键...
【问题讨论】:
标签: python dictionary
我的意思是为什么我们不能把 dict 的键作为 dict?
这意味着我们不能将字典作为另一个字典的键...
【问题讨论】:
标签: python dictionary
简答:因为它们是可变容器。
如果一个字典被散列,它的散列会随着你改变它的内容而改变。
【讨论】:
frozenset(D.items())(对于D 字典)。 frozenset 是一个可散列且不可变的集合——set 是不可散列的,原因与 dict 相同。
这很容易处理。在散列之前将字典包装在 freezeset 中。然后,当您需要使用它时,将其转换回字典。
>>> unhashable = {'b': 'a', 'a': 'b'}
>>> hashable = frozenset(unhashable.items())
>>> unhashable = dict(hashable)
>>> unhashable
{'a': 'b', 'b': 'a'}
请注意,字典键顺序无论如何都是未定义的,因此键顺序的更改无关紧要。
【讨论】:
dict,它将失败
正如其他人所说,dict的哈希值随着内容的变化而变化。
但是,如果您确实需要使用 dicts 作为键,您可以将 dict 子类化以制作可散列的版本。
>>> class hashabledict(dict):
... def __hash__(self):
... return id(self)
...
>>> hd = hashabledict()
>>> d = dict()
>>> d[hd] = "foo"
>>> d
{{}: 'foo'}
>>> hd["hello"] = "world"
>>> d
{{'hello': 'world'}: 'foo'}
这会将用于 dict 的哈希值替换为对象在内存中的地址。
【讨论】:
{} 下存储了一个值,我无法用{} 查找它,因为两个空的hashabledicts 具有不同的id 和不同的哈希值。哈希函数的重要之处在于它必须为两个“相等”的值返回相同的哈希值。
id(),从而导致难以找到的错误。
Python 中的可变容器类型都不是hashable,因为它们是可变的,因此它们的哈希值可以在其生命周期内发生变化。
【讨论】:
([1], {2:3}) 作为字典键。
可能由于错误的原因,我多次遇到这个问题;我想引用完整的dict 作为某事的关键。我不需要它是可变的,但我确实想保留并轻松访问dict 的成员。
我发现使 dict 不可变并快速用作键值的最简单方法是将其设为 JSON(或以您喜欢的替代方式序列化)。
例如:
>>> import json
>>> d = {'hey':1, 'there':2}
>>> d_key = json.dumps(d)
>>> d_key
'{"there": 2, "hey": 1}'
>>> d2 = {d_key: 'crazytown'}
>>> d2
{'{"there": 2, "hey": 1}': 'crazytown'}
它很容易操作,因为它只是一个字符串。而且,如果你想引用它的成员,它可以被反序列化成一个对象。
【讨论】: