2017-04-02 129 views
0

首先,我的目标是:我希望能够将键添加到字典中,并使这些键与多个值关联。举例来说,我希望能有这样的:。Python - 创建一个向字典对象添加键的类+附加特定值

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”以将某些项目附加到该字典密钥。

所以,如果我有 “则newkey” 与list_of_vals = [1,2,3]和LIST_OF_NAMES = [ '高度', '重', '什么'],我希望能够做到这一点:

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]为“富”键的高度属性。

我想在这个类中构建的另一个特性是每次添加新的数字列表时,将新行连接成一个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列包含多个权重值,并且每个每次将行连接到数组的底部。

回答

0

我认为它更多的是你把字典比字典本身的对象的问题。以myDict['myKey1'].height为例,其字典中的对象具有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} 
+0

谢谢!这非常符合我想要的方向。我随后编辑了OP。 – pavlov

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) 
1

我认为习惯Python会避免创建一个像这样的自定义类。相反,你可以使用的字典条目的namedtuple,并且只使用一个字典理解为你的构造:

>>> 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)} 
+0

你和我已经阅读了这个问题非常不同!我认为OP想动态地将属性添加到列表中的对象,而不是像'namedtuple'那样创建带有罐头属性的对象。看看这个过程如何进行会很有趣。 – tdelaney