构造具有多部分键的字典

时间:2013-05-02 09:00:57

标签: python python-2.7 python-3.x

我正在尝试使用具有两个部分k1和k2的键创建字典dict。 k1是实际键,k2是dict [k1,k2]的长度。在下面的例子中,k1是'cat'而k2是10. k2只是值列表的大小,并没有对key的唯一性做出贡献。

dict = {
        cat, 10: [value1, value2, value3, ..., value10],
        dog, 15: [value1, value2, value3, ..., value15],
        zen, 15: [value1, value2, value3, ..., value15]
       }

我所做的是,在没有k2的情况下实现了dict,然后连接了k1和k2,这意味着密钥实际上是k1k2,导致以下实现。

if key not in dict:
  dict[key] = [value1]
else:
  if value_n not in dict[key]:
    dict[key].append(value_n)

for key in dict:
  key = key + str(len(dict[key]))

现在dict就像这样。

dict = {
        cat10: [value1, value2, value3, ..., value10],
        dog15: [value1, value2, value3, ..., value15],
        zen15: [value1, value2, value3, ..., value15]
       }

由于我不想将k2存储在单独的数据结构中,如何在字典中实现多部分键?

2 个答案:

答案 0 :(得分:2)

不确定您的用例是什么。但在我看来,你可以做一些选择之一。这取决于“长度”键(k2)是否是创建列表的原因,或者只是它的指示符。


您可以使用嵌套词典:

dict = {
        'cat' : {10: [value1, value2, value3, ..., value10]},
        'dog' : {15: [value1, value2, value3, ..., value15]},
        'zen' : {15: [value1, value2, value3, ..., value15]}
       }

因此访问将是dict['cat'][10],如果“长度”(k2)只是长度的指示符,这将有效。


您可以创建一个自定义类,使您可以访问“键”并指定您希望该值的长度。该类中的方法将是之类的

def method(self, key, length):
    return self.__dict__[key][:length]

您可以使用元组作为键:

dict = {
        ('cat', 10) : [value1, value2, value3, ..., value10],
        ('dog', 15) : [value1, value2, value3, ..., value15],
        ('zen', 15) : [value1, value2, value3, ..., value15]
       }

答案 1 :(得分:1)

您可以创建一个实施__eq____hash__的课程。然后,您可以将该类的实例用作字典键:

class MyKey(object):
    def __init__(self, animal, length):
        self.__animal = animal
        self.length = length

    @property
    def animal(self):
        return self.__animal

    def __hash__(self):
        return hash(self.__animal)

    def __eq__(self, other):
        return self.__animal == other.animal

    def __repr__(self):
        return "{0}({1}, {2})".format(
            self.__class__.__name__, self.animal, self.length)

我希望我已经正确地理解了你,因为你只想使用动物作为关键词,而捆绑的长度与它一起影响关键词的唯一性。

如你所见,我已经将动物设为只读属性并且名称损坏了基础属性,以防止您无意中更改该属性。如果对用作dict键的实例执行此操作,则会发生 TM 的错误。

请注意,由于dict将MyKey("ox", 9)视为与MyKey("ox", 3)相同的密钥,因此,据我所知,此类代码的行为未指定:

d = {}
d[MyKey("ox", 9)] = "a"
d[MyKey("ox", 3)] = "b"
assert len(d) == 1
# will the key have value 9 or 3? I wouldn't depend on it always being the same.
print d.keys()

所以现在你可以得到这样的代码:

key = MyKey(animal, 0)
if key not in mydict:
    mydict[key] = [value1]
else:
    if value_n not in mydict[key]:
        dict[key].append(value_n)

for key, value in mydict.items():
    key.length = len(value)

所有这一切,你可能更好地以另一种方式解决这个问题。为什么不能在需要长度时直接拨打len(value)?这是一个非常快速的操作(事实上,它只是读取底层python对象的预先计算的变量。)