How to convert a single list into a dictionary? - python

I have a single list in Python like this:
my_list = ['name', 'degree', 'age', 'score']
and would like to convert it into a dictionary that should look like this, where
keys and value are taken from my_list
my_dict = {'name': name, 'degree': degree, 'age' : age, 'score': score}
I found a lot of examples how to convert lists, especially two lists into a dictionary, but nothing for my case.

Use a dictionary comprehension that looks up the variable names in globals()
my_dict = {var: globals()[var] for var in my_list}

Using a dictionary comprehension would probably be the easiest approach:
my_dict = {i:i for i in my_list}

you can use zip with the dictionary constructor:
dict(zip(my_list,my_list))
{'name': 'name', 'degree': 'degree', 'age': 'age', 'score': 'score'}

Related

merge common elements of a list of dictionary and store uncommon elements in a new key

I have a very big dictionary with keys containing a list of items, these are unordered. I would like to group certain elements in a new key. For example
input= [{'name':'emp1','state':'TX','areacode':'001','mobile':123},{'name':'emp1','state':'TX','areacode':'002','mobile':234},{'name':'emp1','state':'TX','areacode':'003','mobile':345},{'name':'emp2','state':'TX','areacode':None,'mobile':None},]
for above input i would like to group areacode and mobile in a new key contactoptions
opdata = [{'name':'emp1','state':'TX','contactoptions':[{'areacode':'001','mobile':123},{'areacode':'002','mobile':234},{'areacode':'003','mobile':345}]},{'name':'emp2','state':'TX','contactoptions':[{'areacode':None,'mobile':None}]}]
i am doing this now with a two long iterations. i wanted to achieve the same more efficiently as the number of records are large. open to using existing methods if available in packages like pandas.
Try
result = (
df.groupby(['name', 'state'])
.apply(lambda x: x[['areacode', 'mobile']].to_dict(orient='records'))
.reset_index(name='contactoptions')
).to_dict(orient='records')
With regular dictionaries, you can do it in a single pass/loop using the setdefault method and no sorting:
data = [{'name':'emp1','state':'TX','areacode':'001','mobile':123},{'name':'emp1','state':'TX','areacode':'002','mobile':234},{'name':'emp1','state':'TX','areacode':'003','mobile':345},{'name':'emp2','state':'TX','areacode':None,'mobile':None}]
merged = dict()
for d in data:
od = merged.setdefault(d["name"],{k:d[k] for k in ("name","state")})
od.setdefault("contactoptions",[]).append({k:d[k] for k in ("areacode","mobile")})
merged = list(merged.values())
output:
print(merged)
# [{'name': 'emp1', 'state': 'TX', 'contactoptions': [{'areacode': '001', 'mobile': 123}, {'areacode': '002', 'mobile': 234}, {'areacode': '003', 'mobile': 345}]}, {'name': 'emp2', 'state': 'TX', 'contactoptions': [{'areacode': None, 'mobile': None}]}]
As you asked, you want to group the input items by 'name' and 'state' together.
My suggestion is, you can make a dictionary which keys will be 'name' plus 'state' such as 'emp1-TX' and values will be list of 'areacode' and 'mobile' such as [{'areacode':'001','mobile':123}]. In this case, the output can be achieved in one iteration.
Output:
{'emp1-TX': [{'areacode':'001','mobile':123}, {'areacode':'001','mobile':123}, {'areacode':'003','mobile':345}], 'emp2-TX': [{'areacode':None,'mobile':None}]}

How to iterate through this nested dictionary within a list using for loop

I have a list of nested dictionaries that I want to get specific values and put into a dictionary like this:
vid = [{'a':{'display':'axe', 'desc':'red'}, 'b':{'confidence':'good'}},
{'a':{'display':'book', 'desc':'blue'}, 'b':{'confidence':'poor'}},
{'a':{'display':'apple', 'desc':'green'}, 'b':{'confidence':'good'}}
]
I saw previous questions similar to this, but I still can't get the values such as 'axe' and 'red'. I would like the new dict to have a 'Description', 'Confidence' and other columns with the values from the nested dict.
I have tried this for loop:
new_dict = {}
for x in range(len(vid)):
for y in vid[x]['a']:
desc = y['desc']
new_dict['Description'] = desc
I got many errors but mostly this error:
TypeError: string indices must be integers
Can someone please help solve how to get the values from the nested dictionary?
You don't need to iterate through the keys in the dictionary (the inner for-loop), just access the value you want.
vid = [{'a':{'display':'axe', 'desc':'red'}, 'b':{'confidence':'good'} },
{'a':{'display':'book', 'desc':'blue'}, 'b':{'confidence':'poor'}},
{'a':{'display':'apple', 'desc':'green'}, 'b':{'confidence':'good'}}
]
new_dict = {}
list_of_dicts = []
for x in range(len(vid)):
desc = vid[x]['a']['desc']
list_of_dicts.append({'desc': desc})
I have found a temporary solution for this. I decided to use the pandas dataframe instead.
df = pd.DataFrame(columns = ['Desc'])
for x in range(len(vid)):
desc = vid[x]['a']['desc']
df.loc[len(df)] = [desc]
so you want to write this to csv later so pandas will help you a lot for this problem using pandas you can get the desc by
import pandas as pd
new_dict = {}
df = pd.DataFrame(vid)
for index, row in df.iterrows() :
new_dict['description'] = row['a']['desc']
a b
0 {'display': 'axe', 'desc': 'red'} {'confidence': 'good'}
1 {'display': 'book', 'desc': 'blue'} {'confidence': 'poor'}
2 {'display': 'apple', 'desc': 'green'} {'confidence': 'good'}
this is how dataframe looks like a b are column of the dataframe and your nested dicts are rows of dataframe
Try using this list comprehension:
d = [{'Description': i['a']['desc'], 'Confidence': i['b']['confidence']} for i in vid]
print(d)

How do you build a nested dict comprehension that imitates 'records' made by '.to_dict'?

I have read a CSV file into Pandas and converted the resulting dataframe into a list of dictionaries for each row using the 'to_dict(orient='records') function. A shortened version of the list looks like this:
records = [{'addjob': 'ADDJOB',
'age': 'AGE',
'disab': 'DISCURR13',
'eth': 'ETHUKEUL',
'full': 'FTPT'},
{'addjob': 'ADDJOB',
'age': 'AGE',
'disab': 'DISCURR13',
'eth': 'ETHUKEUL',
'full': nan}]
I am trying to imitate this structure by using a dict comprehension like so:
cleaned_records = OrderedDict([
{k:v for k,v in i} for i in records
])
EDIT: removed 'OrderedDict' as it was a mistake (error is the same):
cleaned_records = [{k:v for k,v in i} for i in records]
However, it is giving me the following error:
The reason I am trying to do this is so I can remove those keys from the dictionaries whose values are null before passing them to another set of functions.
I've been at this for quite a while now and I'm baffled as to why this dict comprehension is not working. Can anyone help me?
You're just missing the .items() or .iteritems() on the dict extraction.
In [28]: [{k:v for k,v in i.iteritems()} for i in records]
Out[28]:
[{'addjob': 'ADDJOB',
'age': 'AGE',
'disab': 'DISCURR13',
'eth': 'ETHUKEUL',
'full': 'FTPT'},
{'addjob': 'ADDJOB',
'age': 'AGE',
'disab': 'DISCURR13',
'eth': 'ETHUKEUL',
'full': nan}]

Create list with one key of list of dictionaries

this should be an easy one, but because I am not so familiar with python, I haven't quite figured out how it works.
I have the following csv file
name ; type
apple ; fruit
pear ; fruit
cucumber ; vegetable
cherry ; fruit
green beans ; vegetable
What I want to achieve is to list all distinct types with its corresponding name such as:
fruit: apple, pear, cherry
vegetable: cucumber, green beans
Reading it in with csv.DictReader I can generate a list of dictionaries of that csv File, saved in the variable alldata.
alldata =
[
{'name':'apple', 'type':'fruit'},
{'name':'pear', 'type':'fruit'},
...
]
Now I need a list of all distinct type values from alldata
types = ??? #it should contain [fruit, vegetable]
such that I can iterate over the list and extract my names corresponding to these types:
foreach type in types
list_of_names = ??? #extract all values of alldata["type"]==type and put them in a new list
print type + ': ' + list_of_names
Does anybody know, how to achieve this?
You can use list comprehension to solve this problem :
types = set([data['type'] for data in alldata])
list_of_name = [data['name'] for data in alldata if data['type']==type]
More general approach is to use itertools.groupby:
from itertools import groupby
food = [
{'name': 'apple', 'type': 'fruit'},
{'name': 'pear', 'type': 'fruit'},
{'name': 'parrot', 'type': 'vegetable'}]
for group, items in groupby(sorted(food, key=lambda x: x['type']), lambda x: x['type']):
print group, list(items) # here is group and items' objects in the group
result is:
fruit [{'type': 'fruit', 'name': 'apple'}, {'type': 'fruit', 'name': 'pear'}]
vegetable [{'type': 'vegetable', 'name': 'parrot'}]
UPD: sort dict before groupby. Thanks #mgilson for point!
Make an iterator that returns consecutive keys and groups from the iterable. The key is a function computing a key value for each element. If not specified or is None, key defaults to an identity function and returns the element unchanged. Generally, the iterable needs to already be sorted on the same key function.
https://docs.python.org/2/library/itertools.html#itertools.groupby
Use the set structure:
types = set((d['type'] for d in alldata))

Map multiple lists of values to a list of keys in a python dictionary?

I want to map some values(a list of lists) to some keys(a list) in a python dictionary.
I read Map two lists into a dictionary in Python
and figured I could do that this way :
headers = ['name', 'surname', 'city']
values = [
['charles', 'rooth', 'kentucky'],
['william', 'jones', 'texas'],
['john', 'frith', 'los angeles']
]
data = []
for entries in values:
data.append(dict(itertools.izip(headers, entries)))
But I was just wondering is there is a nicer way to go?
Thanks
PS: I'm on python 2.6.7
You could use a list comprehension:
data = [dict(itertools.izip(headers, entries)) for entries in values]
from functools import partial
from itertools import izip, imap
data = map(dict, imap(partial(izip, headers), values))
It's already really nice...
data = [dict(itertools.izip(headers, entries) for entries in values]

Categories