2016-12-02 137 views
2

我正在使用boto3进行python AWS Cognito实现。 jwt.decode在IdToken产生的有效载荷是在一本字典的形式,像这样:仅将python字典列表的值合并为单个字典

{ 
    "sub": "a uuid", 
    "email_verified": True, 
    "iss": "https://cognito-idp....", 
    "phone_number_verified": False, 
    "cognito:username": "19407ea0-a79d-11e6-9ce4-09487ca06884", 
    "given_name": "Aron Filbert", 
    "aud": "my client app", 
    "token_use": "id", 
    "auth_time": 1480547504, 
    "nickname": "Aron Filbert", 
    "phone_number": "+14025555555", 
    "exp": 1480551104, 
    "iat": 1480547504, 
    "email": "[email protected]" 
} 

所以我设计了一个用户类,消耗了字典。很好的工作,直到我需要再次击中Cognito并抓住新的用户细节以确保没有任何变化(例如,从另一个设备)。从get_user()叫我回报的有效载荷最终看起来像一个字典列表:

[ 
    { 
     "Name": "sub", 
     "Value": "a uuid" 
    }, 
    { 
     "Name": "email_verified", 
     "Value": "true" 
    },   
    { 
     "Name": "phone_number_verified", 
     "Value": "false" 
    }, 
    { 
     "Name": "phone_number", 
     "Value": "+114025555555" 
    }, 
    { 
     "Name": "given_name", 
     "Value": "Aron Filbert" 
    }, 
    { 
     "Name": "email", 
     "Value": "[email protected]" 
    }   
] 

因为我可能会打的是get_user() Cognito终点了很多,我在寻找一种有效的方式抓住每个JUST值字典列表中,并使用它们形成键:新字典的值。例如:

{ 
    "sub": "a uuid", # From first list item 
    "email_verified": True, # From next list item   
    ... 
} 

作为Python的新手,我正在努力如何优雅高效地完成此任务。

+1

首先,您应该简单而低效地做到这一点,然后担心改进(这就是您学习的方式)。你尝试过一些简单/暴力吗? –

+0

完全同意。我问的原因是因为我在使用我不熟悉的后端的最后期限。我已经写了一个快速迭代器来完成我的任务,并考虑使用'any()',但是希望得到更多pythonic解决方案 – afilbert

+2

'k [“Name”]:k [“Value”] for k in list_of_dicts_from_get_user}'? –

回答

2

正如我在评论所指出的,你的大部分工作可以通过字典理解做:

lst = get_user() # or something similar, lst is a list of dicts 
parsed_res = {k["Name"]:k["Value"] for k in lst} 

这只是从您的预期输出的不同之处在于它包含'true''false'而你想要的bool在你的最终结果。那么,最简​​单的办法是定义一个函数,这是否转化为你:

def boolify(inp): 
    if inp=='true': 
     return True 
    elif inp=='false': 
     return False 
    else: 
     return inp 

parsed_res = {k["Name"]:boolify(k["Value"]) for k in lst} 

同样的事情可以在修真本身来完成,但它不会是任何清晰,也没有效率。通过这种方式,您可以在您的密钥中进行其他操作,如果您以后认识到在存储之前还有其他您想要对您的有效内容执行的操作。

1

正如安德拉斯在上面回答的那样,字典理解是一种简单的Pythonic单行程式,适合您的情况。有些样式准则(such as Google's),但是,建议对他们是否引入复杂的逻辑或者占用两个以上或三行:

好以用于简单情况。每个部分必须符合一行: 映射表达式,用于子句,过滤器表达式。 子句或过滤器表达式的倍数不允许。当事情变得更加复杂时,请使用循环代替 。

是:

result = [] 
for x in range(10): 
    for y in range(5): 
     if x * y > 10: 
      result.append((x, y)) 

for x in xrange(5): 
    for y in xrange(5): 
     if x != y: 
      for z in xrange(5): 
       if y != z: 
        yield (x, y, z) 

return ((x, complicated_transform(x)) 
     for x in long_generator_function(parameter) 
     if x is not None) 

squares = [x * x for x in range(10)] 

eat(jelly_bean for jelly_bean in jelly_beans 
    if jelly_bean.color == 'black') 

号:

result = [(x, y) for x in range(10) for y in range(5) if x * y > 10] 

return ((x, y, z) 
     for x in xrange(5) 
     for y in xrange(5) 
     if x != y 
     for z in xrange(5) 
     if y != z) 

解释的理解是在您的实例非常合适,但为了完整起见,这是一个通用的方法如果你决定做任何事情,可以用一些for-loops来执行操作:

for <dict> in <list>: 
    for <key>, <value> in <dict>: 
     # Perform any applicable operations. 
     <new_dict>[<key>] = <value> 

哪些出来...

user = get_user() 
user_info = {} 

for info in user: 
    for name, value in info: 
     n, v = info[name], info[value] 
     if v.lowercase() == 'true': 
      v = True 
     else if v.lowercase() == 'false': 
      v = False 
     user_info[n] = v