使用Python字典作为键(非嵌套)

时间:2009-10-21 12:47:53

标签: python data-structures dictionary

Python不允许将字典用作其他字典中的键。是否有使用非嵌套字典作为键的解决方法?

更复杂的不可清除对象和我的特定用例的一般问题是moved here。我对用例的原始描述不正确。

9 个答案:

答案 0 :(得分:53)

如果你有一个真正不可变的字典(虽然我不清楚为什么你不只是使用一对配对列表:例如[('content-type', 'text/plain'), ('host', 'example.com')]),那么你可以将你的dict转换成:

  1. 成对的元组。你已经在你的问题中做到了这一点。需要tuple而不是list,因为结果依赖于元素的排序和不变性。

    >>> tuple(sorted(a.items()))
    
  2. 冷冻套装。从数学的角度来看,这是一种更合适的方法,因为它需要仅对不可变dict的元素使用等式关系,而第一种方法需要除了相等之外的有序关系。

    >>> frozenset(a.items())
    

答案 1 :(得分:8)

如果我需要使用字典作为键,我会将字典拼成一个元组元组。

您可能会发现此问题很有用:What is the best way to implement nested dictionaries?

这是一个扁平模块的例子,它会压缩字典:http://yawpycrypto.sourceforge.net/html/public/Flatten.Flatten-module.html

我不完全了解您的用例,我怀疑您正在尝试过早优化不需要优化的内容。

答案 2 :(得分:4)

执行此操作的一种方法是将dict子类化并提供哈希方法。即:

class HashableDict(dict):
    def __hash__(self):
        return hash(tuple(sorted(self.iteritems())))

>>> d = HashableDict(a=1, b=2)
>>> d2 = { d : "foo"}
>>> d2[HashableDict(a=1, b=2)]
"foo"

但是,请记住dicts(或任何可变类型)不执行此操作的原因:在将对象添加到哈希表后对其进行更改将更改哈希值,这意味着dict现在将在错误的存储桶,因此将返回错误的结果。

如果你走这条路,要么非常确保dicts在放入另一个字典之后永远不会改变,或者主动阻止它们(例如,检查干扰后是否永远不会改变)首先调用__hash__,如果没有则抛出异常。)

答案 3 :(得分:3)

嗯,不是你的用例只是记忆函数调用吗?使用装饰器,您可以轻松支持任意功能。是的,他们经常挑剔参数,并使用循环推理,只要它们可以被腌制,这适用于非标准类型。

参见例如this memoization sample

答案 4 :(得分:2)

要将someDictionary转换为键,请执行此操作

key = tuple(sorted(someDictionary .items())

您可以使用dict( key )

轻松撤消此操作

答案 5 :(得分:0)

我不明白你为什么要这样做,但如果你真的需要,你可以尝试腌制字典:

mydict = {"a":1, "b":{"c":10}}
import pickle
key = pickle.dumps(mydict)

d[key] = value

答案 6 :(得分:0)

此函数会将嵌套字典转换为不可变的元组元组,您可以将其用作键:

def convert_dictionary_tuple(input_dict):
    """
    this function receives a nested dictionary and convert it to an immutable tuple of tuples with all the given
    dictionary data
    :param input_dict: a nested dictionary
    :return: immutable tuple of tuples with all the given dictionary data
    """
    tuples_dict = {}
    for key, value in input_dict.iteritems():
        if isinstance(value, dict):
            tuples_dict[key] = convert_dictionary_tuple(value)
        elif isinstance(value, list):
            tuples_dict[key] = tuple([convert_dictionary_tuple(v) if isinstance(v, dict) else v for v in value])
        else:
            tuples_dict[key] = value

    return tuple(sorted(tuples_dict.items()))

答案 7 :(得分:0)

我将总结这些选项并添加我自己的选项之一, 您可以:

  • 创建一个子类来指示并提供哈希函数
  • 将字典拼凑成元组
  • 给字典上戳
  • 使用json模块将Dict转换为字符串(如下所示)
import json
Dict = {'key' :'value123'}
stringifiedDict = json.dumps(Dict)
print(stringifiedDict)
# {"key": "value123"}
newDict = {stringifiedDict: 12345}
print(newDict[stringifiedDict])
# 12345
for key, val in newDict.items():
    print(json.loads(key))
    # {'key': 'value123'}
    print(json.loads(key)['key'])
    # value123

答案 8 :(得分:-1)

我不知道我是否理解你的问题,但我会试一试

    d[repr(a)]=value

你可以像这样对词典进行交流

for el1 in d:
        for el2 in eval(el1):
                print el2,eval(el1)[el2]