2014-09-01 141 views
1

我有以下結構:Python的 - 嵌套理解列表

input = { 
'clark': { 
      'elements':['id[3]_element[1]','id[3]_element[2]','id[3]_element[3]'], 
      'nickname': 'superman', 
      'registered': 'Y' 
     }, 
'rodger': { 
      'elements':['id[2]_element[1]','id[2]_element[2]','id[2]_element[3]'], 
      'nickname': 'rodjeuur', 
      'registered': 'N' 
     }, 
'ratman': { 
      'elements':['id[6]_element[1]','id[6]_element[2]','id[6]_element[3]'], 
      'nickname': 'rat', 
      'registered': 'Y' 
     }, 
'marylin': { 
      'elements':['id[90]_element[1]','id[90]_element[2]','id[90]_element[3]'], 
      'nickname': 'monroe', 
      'registered': 'Y' 
     }, 
'snoopy': { 
      'elements':['id[1]_element[1]','id[1]_element[2]','id[1]_element[3]'], 
      'nickname': 'lame', 
      'registered': 'N' 
     }, 
'dummy_field[1]': 'dogfood', 
'dummy_field[2]': 'monkeyjump', 
'id[3]_element[1]':{ 
    'feature': 'vision glass', 
    'value': 0.12, 
    'color': 'blue' 
}, 
'id[3]_element[2]':{ 
    'feature': 'height', 
    'value': 1.88 
}, 
'id[3]_element[3]':{ 
    'feature': 'cookingskill', 
    'value': 0 
}, 
'id[6]_element[1]':{ 
    'feature': 'rat teeth', 
    'value': 25, 
    'similarity':'luis suarez' 
}, 
'id[6]_element[2]':{ 
    'feature': 'height', 
    'value': 1.70 
}, 
'id[6]_element[3]':{ 
    'feature': 'cookingskill', 
    'value': 0.5 
}, 
'id[2]_element[1]':{ 
    'feature': 'tennis raquet', 
    'value': 500000, 
    'particularity':'second arm' 
}, 
'id[2]_element[2]':{ 
    'feature': 'height', 
    'value': 1.78 
}, 
'id[2]_element[3]':{ 
    'feature': 'trickshot', 
    'value': 120 
}, 
'id[1]_element[1]':{ 
    'feature': 'mood', 
    'value': 0, 
    'particularity':'depressed' 
}, 
'id[1]_element[2]':{ 
    'feature': 'height', 
    'value': 0.45 
}, 
'id[1]_element[3]':{ 
    'feature': 'sadness', 
    'value': 10000000 
}, 
'id[90]_element[1]':{ 
    'feature': 'charm', 
    'value': 500000 
}, 
'id[90]_element[2]':{ 
    'feature': 'height', 
    'value': 1.72 
}, 
'id[90]_element[3]':{ 
    'feature': 'cookingskills', 
    'value': 0 
} 
} 

和列表要迭代:

lnames=['clark','ratman','snoopy','marylin'] 

我想獲得dictionnaries以下列表作爲結果:

output=[{'vision glass':0.12, 'height':1.88, 'cookingskill':0}, 
    {'rat teeth':25, 'height':1.70, 'cookingskill':0.5}, 
    {'mood':0, 'height':0.45, 'sadness':10000000}, 
    {'charm':500000, 'height':1.72, 'cookingskills':0} 
] 

我開始了非常基本的代碼:

output=[{.... for el in input[name]['elements']} for name in lnames] 

我可以覆蓋每個名稱元素並遍歷它們以訪問不同的「特徵」和「值」,但我不知道如何將它們分組爲字典中的給定名稱。

有沒有人有想法?

EDIT

現在假設我具有相同的輸入,除了有一個 '@' 在每個名稱的字段 '元素':

input = { 
'clark': { 
      'elements':['@id[3]_element[1]','@id[3]_element[2]','@id[3]_element[3]'], 
      'nickname': 'superman', 
      'registered': 'Y' 
     }, 
'rodger': { 
      'elements':['@id[2]_element[1]','@id[2]_element[2]','@id[2]_element[3]'], 
      'nickname': 'rodjeuur', 
      'registered': 'N' 
     }, 
'ratman': { 
      'elements':['@id[6]_element[1]','@id[6]_element[2]','@id[6]_element[3]'], 
      'nickname': 'rat', 
      'registered': 'Y' 
     }, 
'marylin': { 
      'elements':['@id[90]_element[1]','@id[90]_element[2]','@id[90]_element[3]'], 
      'nickname': 'monroe', 
      'registered': 'Y' 
     }, 
'snoopy': { 
      'elements':['@id[1]_element[1]','@id[1]_element[2]','@id[1]_element[3]'], 
      'nickname': 'lame', 
      'registered': 'N' 
     }, 
'dummy_field[1]': 'dogfood', 
'dummy_field[2]': 'monkeyjump', 
'id[3]_element[1]':{ 
    'feature': 'vision glass', 
    'value': 0.12, 
    'color': 'blue' 
}, 
'id[3]_element[2]':{ 
    'feature': 'height', 
    'value': 1.88 
}, 
'id[3]_element[3]':{ 
    'feature': 'cookingskill', 
    'value': 0 
}, 
'id[6]_element[1]':{ 
    'feature': 'rat teeth', 
    'value': 25, 
    'similarity':'luis suarez' 
}, 
'id[6]_element[2]':{ 
    'feature': 'height', 
    'value': 1.70 
}, 
'id[6]_element[3]':{ 
    'feature': 'cookingskill', 
    'value': 0.5 
}, 
'id[2]_element[1]':{ 
    'feature': 'tennis raquet', 
    'value': 500000, 
    'particularity':'second arm' 
}, 
'id[2]_element[2]':{ 
    'feature': 'height', 
    'value': 1.78 
}, 
'id[2]_element[3]':{ 
    'feature': 'trickshot', 
    'value': 120 
}, 
'id[1]_element[1]':{ 
    'feature': 'mood', 
    'value': 0, 
    'particularity':'depressed' 
}, 
'id[1]_element[2]':{ 
    'feature': 'height', 
    'value': 0.45 
}, 
'id[1]_element[3]':{ 
    'feature': 'sadness', 
    'value': 10000000 
}, 
'id[90]_element[1]':{ 
    'feature': 'charm', 
    'value': 500000 
}, 
'id[90]_element[2]':{ 
    'feature': 'height', 
    'value': 1.72 
}, 
'id[90]_element[3]':{ 
    'feature': 'cookingskills', 
    'value': 0 
} 
} 

使用如下因素的代碼:

import re 

def at(x): 
    return input[re.sub(r'@','',x)] 

我相信我可以繼續像這樣的字典理解:

output=[{at(el)['feature']:at(el)['value'] for el in input[name]['elements']} for name in lnames] 

但我得到了錯誤NameError: global name 'at' is not defined。當我使用列表理解,而不是字典解析,它的工作原理,但:

1 - 我仍然不知道這個名字錯誤的意思,因爲它與字典解析。 2 - 這不是預期的結果。相比於最初的回答

編輯沒有那麼複雜,但點1 /跟我沒關係!

回答

3

你幾乎在那裏。它應該是:

output=[{input[el]['feature']:input[el]['value'] 
    for el in input[name]['elements']} for name in lnames] 
+0

Thnaks,這個答案非常的第一個問題,但我很遺憾不得不添加一個編輯的全面解決方案! – 2014-09-02 07:16:15

+0

我用你的編輯代碼生成字典列表沒有問題。 ()在哪裏宣佈?順便說一句,沒有必要使用正則表達式來進行這樣簡單的替換。你可以使用'return input [x.replace('@','')]' – klasske 2014-09-02 08:04:52

+0

在聲明'output = [{at(el)['feature']之前聲明它:at(el)['輸入[名稱] ['元素']}中的名稱]中輸入el的值]。我正在使用Python 2.7 – 2014-09-02 13:46:15

0

它有時可以寫出常規循環,然後轉換爲列表理解。這樣做之後,我得到了下面的代碼:

output = [{input[element]['feature']: input[element]['value'] 
      for element in input[name]['elements']} 
      for name in lnames] 
1

與存在檢查

output = [ 
    { 
     input[element]['feature'] : input[element]['value'] 
     for element in input.get(name,{}).get('elements',[]) 
    } 
    for name in lnames 
]