2013-05-10 91 views
1

我有一個返回以下字典字典包含列表

abc= {"type":"insecure","id":"1", 
     "name":"peter","s_count":"2", 
     "b_count":"1", "s_1_name":"melisa", 
     "s_1_id":"2","s_2_name":"graham", 
     "s_2_id":"4", "b_1_name":"henrik", 
     "b_1_id": "9"} 

我想恰克下列方式字典的功能:

xyz={"type":"insecure","id":"1", 
    "name":"peter", 
     "s" : [{"id" : "2", "name": "melisa"}, 
      {"id" : "4", "name": "graham"}], 
     "b" : [{"id" : "9", "name": "henrik"}]} 

的邏輯如下:如果有s_count在字典中,然後創建一個列表,其中包含以s開頭的所有值。例如,在我的情況下創建包含與每個字典不同的字典包含S_NAME和S_ID例如在我的情況下,有兩個字典在結果列表中AA列表:

"s" : [{"id" : "2", "name": "melisa"},{"id" : "4", "name": "graham"}] 

,做同樣的用b,以及如果b_count計數存在。

有人能幫我解決嗎?

+2

莫不是'a_count'或'c_count '或者只是你提到的那兩個? – jamylak 2013-05-10 15:09:59

+0

不,它只會有s_count和b_count或者沒有以前綴s_或b_開頭的值。 – hjelpmig 2013-05-10 16:56:35

+1

我不同意這太局部化了;投票重新開放。底層的一般問題是如何高效地使用通用前綴處理字典密鑰。 – 2013-05-11 13:05:18

回答

4

我會使用一個輔助函數:

>>> extract_keys(abc, 's') 
[{'id': '2', 'name': 'melisa'}, {'name': 'graham', 'id': '4'}] 
>>> extract_keys(abc, 'b') 
[{'name': 'henrik', 'id': '9'}] 

使用該函數來創建新的詞典或就地改造現有字典:

from itertools import groupby 
from operator import itemgetter 

def extract_keys(mapping, prefix): 
    prefix = '{}_'.format(prefix) 

    # test for the `.._count` key first, if it's not there, bail out early 
    if prefix + 'count' not in mapping: 
     return None 

    # find all matching keys, split out the counter for sorting and grouping 
    keys = [(k, int(k.split('_', 2)[1])) 
     for k in mapping if k.startswith(prefix) and k != prefix + 'count'] 
    keys.sort(key=itemgetter(1)) 

    # group keys on the counter, then generate a dictionary per counter value 
    return [{k[0].split('_', 2)[-1]: mapping[k[0]] for k in group} 
     for c, group in groupby(keys, itemgetter(1))] 

此功能通過前綴提取鍵:

xyz = {k: v for k, v in abc.iteritems() if not k.startswith('s_') and not k.startswith('b_')} 
s_values = extract_keys(abc, 's') 
if s_values is not None: 
    xyz['s'] = s_values 
b_values = extract_keys(abc, 'b') 
if b_values is not None: 
    xyz['b'] = b_values 

這會將您的abc樣品輸入到:

>>> pprint(xyz) 
{'b': [{'id': '9', 'name': 'henrik'}], 
'id': '1', 
'name': 'peter', 
's': [{'id': '2', 'name': 'melisa'}, {'id': '4', 'name': 'graham'}], 
'type': 'insecure'} 
+0

感謝您的幫助。它解決了我的問題。我也改進了一些代碼,使其更加靈活,並且可以處理所有拆分,但不能發佈,因爲問題已關閉:('code'#找到所有匹配的鍵,拆分計數器進行排序和分組 keys = [ (k,int)(k.split('_',-1)[ - 2])) key.sort(key = itemgetter(1)) #在計數器上的組密鑰 return {{k [0] .split('_',-1)[ - 1]:映射[k [0]]在組中} 對於c組groupby(keys,itemgetter(1))] – hjelpmig 2013-05-11 13:05:27

0

我改進了一點,使它變得更加靈活。

def extract_keys(mapping, prefix): 
prefix = "{}_".format(prefix) 

# test for the `.._count` key first, if it's not there, bail out early 
if prefix + "count" not in mapping: 
    return None 

# find all matching keys, split out the counter for sorting and grouping 
keys = [(k, int(k.split("_", -1)[-2])) for k in mapping if k.startswith(prefix) and k != prefix + "count"] 
keys.sort(key=itemgetter(1)) 

# group keys on the counter, then generate a dictionary per counter value 
return [{k[0].split("_", -1)[-1]: mapping[k[0]] for k in group} for c, group in groupby(keys, itemgetter(1))] 

請考慮以下詞典。

abc= {"type":"insecure","id":"1", 
    "name":"peter","s_a_count":"2", 
    "b_count":"1", "s_a_1_name":"melisa", 
    "s_a_1_id":"2","s_a_2_name":"graham", 
    "s_a_2_id":"4", "b_1_name":"henrik", 
    "b_1_id": "9"} 

使用該函數來創建新的詞典或就地改造現有字典:

xyz = {k: v for k, v in abc.iteritems() if not k.startswith('s_a') and not k.startswith('b_')} 
s_values = extract_keys(abc, 's_a') 
if s_values is not None: 
    xyz['s_a'] = s_values 
b_values = extract_keys(abc, 'b') 
if b_values is not None: 
    xyz['b'] = b_values 

,並轉化輸出爲:

print xyz 

{'b': [{'id': '9', 'name': 'henrik'}], 
'id': '1', 
'name': 'peter', 
's_a': [{'id': '2', 'name': 'melisa'}, {'id': '4', 'name': 'graham'}], 
'type': 'insecure'} 
+0

評論將被appretiated – hjelpmig 2013-05-11 14:28:37