2017-03-03 38 views
2

我有這樣的代碼:提取值

class B(): 

     def __init__(self, valueA, valueB): 
      self.valueA = valueA 
      self.valueB = valueB 


     def __repr__(self): 
      return 'B({0},{1})'.format(self.valueA, self.valueB)  

我的數據是:

thedata = {'a': [B(1, 0.1),B(2, 0.2)], 
      'b': [B(3, 0.3),B(4, 0.4)]} 

我想要做的就是從上面字典提取ab屬性根據關鍵字2個新詞典。

所以,我想:

thedata_a_valueA = {'a':[1, 2]} 
thedata_a_valueB = {'a':[0.1, 0.2]} 
thedata_b_valueA = {'b':[3, 4]} 
thedata_b_valueB = {'b':[0.3, 0.4]} 

最後我想2點字典:

newdict_valueA = {'a':[1, 2], 'b':[3,4]} 
newdict_valueB = {'a':[0.1, 0.2], 'b':[0.3,0.4]} 

一種解決方案是使用列表,但我必須創造相當多的名單,在其中循環,追加etc

thedata有沒有更清潔/更快的解決方案?

+1

唐忘記Python字典不支持重複鍵。因此,在newdict_valueB示例中不可能使用兩個具有不同值的'b'鍵。 –

+0

@MarkStreatfield:對不起,這是一個錯字。 – George

回答

1

像這樣將工作:

# Starting from two empty dictionaries 
newdict_valueA, newdict_valueB = {}, {} 

# Iterate over the key/value pairs of the data 
for key, value in thedata.items(): 
    # assign to the same key of each result dictionary a list of 
    # the valueA for each B item in the value of the original dictionary 
    newdict_valueA[key] = [item.valueA for item in value] 
    newdict_valueB[key] = [item.valueB for item in value] 

newdict_valueA:

{'a': [1, 2], 'b': [3, 4]} 

newdict_valueB:

{'a': [0.1, 0.2], 'b': [0.3, 0.4]} 
0

你可以擁有所有預期的項目在列表中的每個關鍵你的字典。您只需循環使用thedata的項目,併爲每個密鑰創建一個包含valueAvalueB的單獨項目的字典。 dict.setdefault()屬性將是此任務的不錯選擇。

In [18]: d = {} 

In [19]: for i, j in thedata.items(): 
      for instance in j: 
       d.setdefault(i, {}).setdefault('valueA', []).append(instance.valueA) 
       d.setdefault(i, {}).setdefault('valueB', []).append(instance.valueB)  

In [20]: d 
Out[21]: 
{'a': {'valueB': [0.1, 0.2], 'valueA': [1, 2]}, 
'b': {'valueB': [0.3, 0.4], 'valueA': [3, 4]}} 

注意,作爲更清潔的方式,你可以使用collections.defaultdict()代替dict.setdefault()方法:

In [33]: d = defaultdict(lambda: defaultdict(list)) 

In [34]: for i, j in thedata.items(): 
      for instance in j: 
       d[i]['valueA'].append(instance.valueA) 
       d[i]['valueB'].append(instance.valueB) 
    ....:   

In [35]: d 
Out[35]: defaultdict(<function <lambda> at 0x7fb5888786a8>, 
     {'a': defaultdict(<class 'list'>, 
       {'valueB': [0.1, 0.2], 'valueA': [1, 2]}), 
      'b': defaultdict(<class 'list'>, 
       {'valueB': [0.3, 0.4], 'valueA': [3, 4]})}) 
0

如果我收到了你的問題的權利,你可以使用內涵:

newdict_valueA = { k : [ b.valueA for b in l ] for k, l in thedata.items() } 
newdict_valueB = { k : [ b.valueB for b in l ] for k, l in thedata.items() }