简体   繁体   中英

How to reduce convert list of Dict to Dict in Python

I have a requirement to convert list of dict in below format.

[{"key":"eff_date","value":"20202020"},{"key":"member_id","value":"33sasfafXCC"},{"key":"exp_date","value":"20992020"}]

into this format:

{"eff_date":"20202020","member_id":"33sasfafXCC","exp_date":"20992020"}

I tried reduce function with below but couldn't quite getting it.

payload = [{"key":"eff_date","value":"20202020"},{"key":"member_id","value":"33sasfafXCC"},{"key":"exp_date","value":"20992020"}]    
list = []
    def keys(x,y):
     return list.append({y['key'] : y['value']})

result = reduce(keys, payload,None)

You don't really need reduce . You aren't reduce -ing anything.

Try a simple dictionary comprehension:

result = {p["key"]:p["value"] for p in payload}

>>> result
{'eff_date': '20202020', 'member_id': '33sasfafXCC', 'exp_date': '20992020'}

You can edit your function to look as so:

payload = [{"key":"eff_date","value":"20202020"},{"key":"member_id","value":"33sasfafXCC"},{"key":"exp_date","value":"20992020"}]    

def change(list):
  newDict = {}
  for dict in payload:
    newDict[dict["key"]] = dict["value"]
  return newDict

result = change(payload)
print(result)

Output:

{'eff_date': '20202020', 'member_id': '33sasfafXCC', 'exp_date': '20992020'}

This will take in a list of dictionaries, iterate through every dictionary, add the key-value pair into a new dictionary, and then return that dictionary.

As @not_speshal mentioned, you don't need the built-in reduce function.

Note, you could do this with functools.reduce , although, you really should just use a dictionary comprehension, but one efficient solution would be:

>>> from functools import reduce
>>> data = [{"key":"eff_date","value":"20202020"},{"key":"member_id","value":"33sasfafXCC"},{"key":"exp_date","value":"20992020"}]
>>> def reducer(acc, x):
...     acc[x['key']] = x['value']
...     return acc
...
>>> reduce(reducer, data, {})
{'eff_date': '20202020', 'member_id': '33sasfafXCC', 'exp_date': '20992020'}

Which is not pretty - it relies on side-effects. Might as well just be a for-loop if you are going to rely on side-effects.

A more "principled" way that doesn't rely on side-effects using the new pip-update operator | would be:

>>> def reducer(acc, x):
...     return acc | {x['key']:x['value']}
...
>>> reduce(reducer, data, {})
{'eff_date': '20202020', 'member_id': '33sasfafXCC', 'exp_date': '20992020'}

But this would be unnecessarily inefficient, and would scale poorly.

So in summary, the most natural way to do this in Python is simply:

result = {x['key']: x['value'] for x in data}

Or even just the for-loop form:

result = {}
for x in data:
    result[x['key']] = x['value']

Would be much preferable to either reduce based solution

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM