Python - 创建一个为字典对象添加键的类+附加特定值

时间:2017-04-02 22:26:57

标签: python class dictionary

首先,这是我的目标:我希望能够将键添加到字典中,并使这些键与许多值相关联。例如,我希望能够有类似的东西:

myDict [ 'myKey1']。高度 myDict [ 'myKey1']。重量

我希望能够为此添加新密钥,例如myDict ['myKey2'],这样我也可以选择将高度和权重值附加到新密钥,如上所述。

这是我到目前为止所得到的:

class Vividict(dict):
    def __missing__(self, key):
        value = self[key] = type(self)()
        return value

我一直在使用上面的类为词典添加新键。我不仅要做这个,还要输入列表,这样我就可以通过在我的类中添加类似这样的新键来查找“高度”和“重量”之类的内容。

def __init__(self, list_of_vals, list_of_names):

    for x,y in zip(list_of_vals, list_of_names):
        self.(y) = x

我知道上面的错误,但我希望有人能看到我在这里想要实现的目标。我想定义一个类,以便我可以向字典添加新密钥,并提供“list_of_vals”和“list_of_names”以将某些项附加到该字典键。

所以,如果我有list_of_vals = [1,2,3]和list_of_names = ['height','weight','what']的“newKey”,我希望能够这样做:

myDict['newKey'].height = 1
myDict['newKey'].weight = 2
myDict['newKey'].whatever = 3

我希望这是有道理的。我有点想模仿我在Matlab中使用结构做什么。

谢谢!

---- ----更新

import collections

class Vals:

    def add(self, list_of_vals=[], list_of_names=[]):
        for val, name in zip(list_of_vals, list_of_names):
            setattr(self, name, val)

    def __str__(self):
        return str(self.__dict__)

mydict = collections.defaultdict(Vals)
mydict['Foo'].add([1,2], ['height', 'weight'])

上面提到的tdelaney是我想要移动的方向。谢谢!

如果我采用上面的代码来添加高度和重量属性。如果它们存在,我希望能够添加它们。例如,像:

mydict['Foo'].add([3,4], ['height'])

这样会导致:

mydict['Foo'].height = [1,2,3,4]

换句话说,我将[3,4]添加到'Foo'键的height属性中。

我想在这个类中构建的另一个特性是每次添加新的数字列表时将新行连接成一个numpy数组。例如,如果我从这开始:

mydict['Foo'].add([1,2], ['height', 'weight'])

然后这样做:

mydict['Foo'].add([3,4], ['height', 'weight'])

我希望以下结尾:

mydict['Foo'].height = [1,3]
mydict['Foo'].weight = [2,4]
mydict['Foo'].array = [1, 2; 3, 4]

换句话说,我每次都会添加高度和重量属性,这样我就可以使用新数据添加到增长列表中。同时,我想让类初始化一个空的numpy数组,我们将逐行添加,这样每行包含高度和重量,第1列包含多个高度值,第2列包含多个权重值,每个每次都会将行连接到数组的底部。

3 个答案:

答案 0 :(得分:2)

我认为惯用Python会避免为这样的事情创建一个自定义类。相反,您可以使用namedtuple作为dict条目,并使用dict理解作为构造函数:

>>> from collections import namedtuple

>>> list_of_names = ["Clumsy", "Smurfette"]
>>> list_of_vals = [[1,2,3],[4,5,6]]

>>> Smurf = namedtuple("Smurf", ("height", "weight", "whatever"))

>>> mydict = {k:Smurf(*v) for k,v in zip(list_of_names, list_of_vals)}
>>> print(mydict)

{'Clumsy': Smurf(height=1, weight=2, whatever=3), 'Smurfette': Smurf(height=4, weight=5, whatever=6)}

答案 1 :(得分:1)

我认为它更多的是你在字典中放置的对象而不是字典本身的问题。以myDict['myKey1'].height为例,它在dict中具有height属性的对象。

由于您可以向大多数对象添加属性,因此您只需要定义一个非常精简的类来创建这些对象。您可以让该类按列表添加属性。然后,您可以使用collections.defaultdict,以便在使用字典时动态创建对象。

import collections

class Vals:

    def add(self, list_of_vals=[], list_of_names=[]):
        for val, name in zip(list_of_vals, list_of_names):
            setattr(self, name, val)

    def __str__(self):
        return str(self.__dict__)

mydict = collections.defaultdict(Vals)
mydict['Foo'].height = 1
mydict['Foo'].weight = 2
mydict['Foo'].add([1,2,3], ['a', 'b', 'c'],)
mydict['Bar'].add([10,11,12], 'def')
mydict['Baz'].something_else = 'hello'

assert mydict['Foo'].height == 1
assert mydict['Foo'].weight == 2
assert mydict['Foo'].a == 1
assert mydict['Foo'].b == 2
assert mydict['Foo'].c == 3


for name, obj in mydict.items():
    print(name, obj)

结果

Baz {'something_else': 'hello'}
Bar {'d': 10, 'f': 12, 'e': 11}
Foo {'c': 3, 'height': 1, 'b': 2, 'weight': 2, 'a': 1}

答案 2 :(得分:0)

如下所示?

class Vividict(dict):
    def __missing__(self, key):
        value = self[key] = type(self)()
        return value
    def __init__(self, list_of_vals=[], list_of_names=[]):
        for x,y in zip(list_of_vals, list_of_names):
           setattr(self, x, y)