2016-12-02 138 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