how to convert list of dict to dict
Question:
How to convert list of dict to dict. Below is the list of dict
data = [{'name': 'John Doe', 'age': 37, 'sex': 'M'},
{'name': 'Lisa Simpson', 'age': 17, 'sex': 'F'},
{'name': 'Bill Clinton', 'age': 57, 'sex': 'M'}]
to
data = {'John Doe': {'name': 'John Doe', 'age': 37, 'sex': 'M'},
'Lisa Simpson': {'name': 'Lisa Simpson', 'age': 17, 'sex': 'F'},
'Bill Clinton': {'name': 'Bill Clinton', 'age': 57, 'sex': 'M'}}
Answers:
A possible solution using names as the new keys:
new_dict = {}
for item in data:
name = item['name']
new_dict[name] = item
With python 3.x you can also use dict comprehensions for the same approach in a more nice way:
new_dict = {item['name']:item for item in data}
As suggested in a comment by Paul McGuire, if you don’t want the name in the inner dict, you can do:
new_dict = {}
for item in data:
name = item.pop('name')
new_dict[name] = item
Perhaps you want the name to be the key? You don’t really specify, since your second example is invalid and not really meaningful.
Note that my example removes the key “name” from the value, which may be desirable (or perhaps not).
data = [{'name': 'John Doe', 'age': 37, 'sex': 'M'},
{'name': 'Lisa Simpson', 'age': 17, 'sex': 'F'},
{'name': 'Bill Clinton', 'age': 57, 'sex': 'M'}]
newdata = {}
for entry in data:
name = entry.pop('name') #remove and return the name field to use as a key
newdata[name] = entry
print newdata
##{'Bill Clinton': {'age': 57, 'sex': 'M'},
## 'John Doe': {'age': 37, 'sex': 'M'},
## 'Lisa Simpson': {'age': 17, 'sex': 'F'}}
print newdata['John Doe']['age']
## 37
If the dicts wouldnt share key, then you could use:
dict((key,d[key]) for d in data for key in d)
Probably its better in your case to generate a dict with lists as values?
newdict={}
for k,v in [(key,d[key]) for d in data for key in d]:
if k not in newdict: newdict[k]=[v]
else: newdict[k].append(v)
This yields:
>>> newdict
`{'age': [37, 17, 57], 'name': ['John Doe', 'Lisa Simpson', 'Bill Clinton'], 'sex': ['M', 'F', 'M']}`
With python
3.3
and above, you can use ChainMap
A ChainMap groups multiple dicts or other mappings together to create
a single, updateable view. If no maps are specified, a single empty
dictionary is provided so that a new chain always has at least one
mapping.
from collections import ChainMap
data = dict(ChainMap(*data))
Try this approach:
{key: val} for k in data for key, val in k.items())
Just in case you wanted a functional alternative (also assuming the names are wanted as the new keys), you could do
from toolz.curried import *
data = [{'name': 'John Doe', 'age': 37, 'sex': 'M'},
{'name': 'Lisa Simpson', 'age': 17, 'sex': 'F'},
{'name': 'Bill Clinton', 'age': 57, 'sex': 'M'}]
newdata = pipe(data,
map(lambda x: {x['name']: dissoc(x, 'name')}),
lambda x: merge(*x)
)
print(newdata)
Let’s not over complicate this:
simple_dictionary = dict(data[0])
import pandas as pd
data = [{'name': 'John Doe', 'age': 37, 'sex': 'M'},
{'name': 'Lisa Simpson', 'age': 17, 'sex': 'F'},
{'name': 'Bill Clinton', 'age': 57, 'sex': 'M'}]
print(pd.DataFrame(data).to_dict())
My 5 cents, didn’t like any of answers:
from functools import reduce
collection = [{'hello': 1}, {'world': 2}]
answer = reduce(lambda aggr, new: aggr.update(new) or aggr, collection, {})
How to convert list of dict to dict. Below is the list of dict
data = [{'name': 'John Doe', 'age': 37, 'sex': 'M'},
{'name': 'Lisa Simpson', 'age': 17, 'sex': 'F'},
{'name': 'Bill Clinton', 'age': 57, 'sex': 'M'}]
to
data = {'John Doe': {'name': 'John Doe', 'age': 37, 'sex': 'M'},
'Lisa Simpson': {'name': 'Lisa Simpson', 'age': 17, 'sex': 'F'},
'Bill Clinton': {'name': 'Bill Clinton', 'age': 57, 'sex': 'M'}}
A possible solution using names as the new keys:
new_dict = {}
for item in data:
name = item['name']
new_dict[name] = item
With python 3.x you can also use dict comprehensions for the same approach in a more nice way:
new_dict = {item['name']:item for item in data}
As suggested in a comment by Paul McGuire, if you don’t want the name in the inner dict, you can do:
new_dict = {}
for item in data:
name = item.pop('name')
new_dict[name] = item
Perhaps you want the name to be the key? You don’t really specify, since your second example is invalid and not really meaningful.
Note that my example removes the key “name” from the value, which may be desirable (or perhaps not).
data = [{'name': 'John Doe', 'age': 37, 'sex': 'M'},
{'name': 'Lisa Simpson', 'age': 17, 'sex': 'F'},
{'name': 'Bill Clinton', 'age': 57, 'sex': 'M'}]
newdata = {}
for entry in data:
name = entry.pop('name') #remove and return the name field to use as a key
newdata[name] = entry
print newdata
##{'Bill Clinton': {'age': 57, 'sex': 'M'},
## 'John Doe': {'age': 37, 'sex': 'M'},
## 'Lisa Simpson': {'age': 17, 'sex': 'F'}}
print newdata['John Doe']['age']
## 37
If the dicts wouldnt share key, then you could use:
dict((key,d[key]) for d in data for key in d)
Probably its better in your case to generate a dict with lists as values?
newdict={}
for k,v in [(key,d[key]) for d in data for key in d]:
if k not in newdict: newdict[k]=[v]
else: newdict[k].append(v)
This yields:
>>> newdict
`{'age': [37, 17, 57], 'name': ['John Doe', 'Lisa Simpson', 'Bill Clinton'], 'sex': ['M', 'F', 'M']}`
With python
3.3
and above, you can use ChainMap
A ChainMap groups multiple dicts or other mappings together to create
a single, updateable view. If no maps are specified, a single empty
dictionary is provided so that a new chain always has at least one
mapping.
from collections import ChainMap
data = dict(ChainMap(*data))
Try this approach:
{key: val} for k in data for key, val in k.items())
Just in case you wanted a functional alternative (also assuming the names are wanted as the new keys), you could do
from toolz.curried import *
data = [{'name': 'John Doe', 'age': 37, 'sex': 'M'},
{'name': 'Lisa Simpson', 'age': 17, 'sex': 'F'},
{'name': 'Bill Clinton', 'age': 57, 'sex': 'M'}]
newdata = pipe(data,
map(lambda x: {x['name']: dissoc(x, 'name')}),
lambda x: merge(*x)
)
print(newdata)
Let’s not over complicate this:
simple_dictionary = dict(data[0])
import pandas as pd
data = [{'name': 'John Doe', 'age': 37, 'sex': 'M'},
{'name': 'Lisa Simpson', 'age': 17, 'sex': 'F'},
{'name': 'Bill Clinton', 'age': 57, 'sex': 'M'}]
print(pd.DataFrame(data).to_dict())
My 5 cents, didn’t like any of answers:
from functools import reduce
collection = [{'hello': 1}, {'world': 2}]
answer = reduce(lambda aggr, new: aggr.update(new) or aggr, collection, {})