2015-11-04 70 views
0
使用用於環路獲得從字典數據

我的輸入是通過在Python

[['apple',{'john':3,'anna':4,'kitty':6}],['pear',{'john':4,'anna':3,'kitty':3}]] 

預期輸出:

{ 
    'key':['apple','pear'], 
    'value':[ 
     { 
      'name':'john', 
      'data':[3,4] 
     }, 
     { 
      'name':'anna', 
      'data':[4,3] 
     }, 
     { 
      'name':'kitty', 
      'data':[6,3] 
     } 
    ] 
} 

key是締結每個項目的第一部分,例如一個列表'apple''pear',而value是另一個列表。

我應該怎麼做?

+7

想分享你的企圖我們? – vaultah

回答

2

您可以用collections.defaultdict幫助實現這一點:

from collections import defaultdict 
value, key = defaultdict(list), [] 

for x in l: 
    key.append(x[0]) 
    for k, v in x[1].items(): 
     value[k].append(v) 

要得到的結果:

In [15]: {'key': key, 'value': [{'name': k, 'data': v} for k, v in value.items()]} 
Out[15]: 
{'key': ['apple', 'pear'], 
'value': [ 
    {'data': [4, 3], 'name': 'anna'}, 
    {'data': [6, 3], 'name': 'kitty'}, 
    {'data': [3, 4], 'name': 'john'}]} 

爲了更有效的(?)版本,子類defaultdict自定義默認__missing__鉤來調用default_factory缺少關鍵的參數(我複製這個文本,並從other answer of mine實現)。然後,你就可以做到這一點在單次:

from collections import defaultdict 

class mydefaultdict(defaultdict): 
    def __missing__(self, key): 
     self[key] = value = self.default_factory(key) 
     return value 

# pass 'name' to the dictionary 
value = mydefaultdict(lambda name: {'name': name, 'data': []}) 
key = [] 

for x in l: 
    key.append(x[0]) 
    for k, v in x[1].items(): 
     value[k]['data'].append(v) 

所以,結果是

In [24]: {'key': key, 'value': value.values()} 
Out[24]: 
{'key': ['apple', 'pear'], 
'value': [ 
    {'data': [4, 3], 'name': 'anna'}, 
    {'data': [6, 3], 'name': 'kitty'}, 
    {'data': [3, 4], 'name': 'john'}]} 

在Python 3,你必須調用list(value.values()),而不是僅僅value.values()獲得list對象。

+0

它給了我很大的靈感,謝謝 – user1594252

1

您可以使用下面的代碼片段:

input = [['apple',{'john':3,'anna':4,'kitty':6}],['pear',{'john':4,'anna':3,'kitty':3}]] 

tmp = {} 
output = {'key': [], 'value': []} 

for item in input: 
    output['key'].append(item[0]) 
    for name in item[1]: 
     try: 
      tmp[name].append(item[1][name]) 
     except KeyError: 
      tmp[name] = [item[1][name]] 

output['value'] = [{'name': name, 'data': data} for name, data in tmp.items()] 
1

此功能可以幫助您

def map_data(data): 
    _tmp = {} 
    _keys = [] 
    for _d in data: 
     _keys.append(_d[0]) 
     for _k in _d[1].keys(): 
      _v = _tmp.get(_k) 
      if not _v: 
       _v = {"name": _k, "data": []} 

      _v["data"].append(_d[1][_k]) 
      _tmp[_k] = _v 

    return {"key": _keys, "value": [_v for _v in _tmp.values()]} 
1

這裏是我的解決方案:

import json                       

my_list = [['apple',{'john':3,'anna':4,'kitty':6}],['pear',{'john':4,'anna':3,'kitty':3}]] 

name_list = [item[1] for item in my_list] # [{'john': 3, 'kitty': 6, 'anna': 4}, {'john': 4, 'kitty 
names = name_list[0].keys() # ['john', 'kitty', 'anna']      
name_values = [[item[key] for item in name_list] for key in names] # [[3, 4], [6, 3], [4, 3]] 
result = {                  
    'key': [item[0] for item in my_list],          
    'value': [                 
     {'name': name, 'value': value}           
     for (name, value) in zip(names, name_values)       
    ]                   
}                    

print(json.dumps(result, indent=4)) 

和輸出:

{ 
    "value": [ 
     { 
      "name": "john", 
      "value": [ 
       3, 
       4 
      ] 
     }, 
     { 
      "name": "kitty", 
      "value": [ 
       6, 
       3 
      ] 
     }, 
     { 
      "name": "anna", 
      "value": [ 
       4, 
       3 
      ] 
     } 
    ], 
    "key": [ 
     "apple", 
     "pear" 
    ] 
} 

編輯:

emmm,只是找到了一個更好的方式來合併字典值。

如果name_dict象這樣:

>>> name_dict 
[{'john': [3], 'kitty': [6], 'anna': [4]}, {'john': [4], 'kitty': [3], 'anna': [3]}] 

任務會很容易。有什麼不同?該值是一個列表。

現在,我們可以用collections.Counter來合併兩個詞典!

>>> Counter(name_dict[0]) + Counter(name_dict[1]) 
Counter({'kitty': [6, 3], 'anna': [4, 3], 'john': [3, 4]}) 

所以這裏是新的解決方案,我們首先將值轉換到一個列表:(跳過「密鑰」,只顯示「值」):

from collections import Counter 

    my_list = [['apple',{'john':3,'anna':4,'kitty':6}],['pear',{'john':4,'anna':3,'kitty':3}]] 
    name_list = [item[1] for item in my_list]  

    for item in name_list:               
     for key, value in item.items():            
      item[key] = [value]              

    name_values = dict(Counter(name_list[0]) + Counter(name_list[1])) # {'john': [3, 4], 'kitty': [6, 3], 'anna': [4, 3]}    

    print([{'name': name, 'value': value} for (name, value) in name_values.items()]) 

    # output 
    [{'name': 'john', 'value': [3, 4]}, {'name': 'kitty', 'value': [6, 3]}, {'name': 'anna', 'value': [4, 3]}] 
+0

謝謝,我以同樣的方式解決了 – user1594252

+0

這是一個很好的方式,如果name_list是一個巨大的對象呢? – user1594252

+0

@ user1594252啊,它就是'name_list = [my_list中item的item [1]]',就在這個答案的第一個版本中。 –