2014-09-01 142 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 
]