Unpack a list of dictionaries to an object in Python - python

I am not sure how to ask this as I'm not sure if I'm using the proper key words. I have a dictionaries in a variable x. I unpack (is that the right term?) to a object of type Org like so:
org = Org(**x)
where x is of the form:
{'user': 'joe#example.com', 'sk': 'meta_3', 'location': 'Dubai', 'name': 'Thomas'}
This works so far. I get an object org of type Org.
But my Q is: how do I handle if x is a list of dicts i.e. x is
[
{'user': 'joe#example.com', 'sk': 'meta_3', 'location': 'Dubai', 'name': 'Thomas'},
{'user': 'sam#example.com', 'sk': 'meta_4', 'location': 'Spain', 'name': 'Sam'}
]
How do I unpack that to a list of Org objects?

If x_list is your list containing dicts:
org_list = []
for x in x_list:
org = Org(**x)
org_list.append(org)
Now you have a list org_list that contains all created Org objects.

Related

Get list items that don't match most frequent value

I have a list of dictionaries looking like this:
[{'customer': 'Charles', 'city': 'Paris'}, {'customer': 'John', 'city': 'New York'}, {'customer': 'Jean', 'city': 'Paris'}]
I tried something using collections which will return me the name of the most common city in this list of dictionaries:
city_counts = Counter(c['city'] for c in customers)
return city_counts .most_common(1)[0][0]
From this, I would like to return a list of all customers who are not in this city.
So, if I take the list I gave above, ['John'] should be the output.
I there a best way to do it ?

How to convert a single list into a dictionary?

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'}

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}]}

Separating the data from a string filled with multiple data types

I want to turn this string into a list of the dictionaries within it:
”[{‘id’: ‘x’, ‘name’: ‘y’}, {‘id’: ‘p’, ‘name’: ‘q’}]”
I have multiple columns in a pandas dataframe composed of similar strings to this. Some are only ”[]” or ”[{‘id’: ‘x’, ‘name’: ‘y’}]”, and others have many stringified dictionaries within them.
I have tried
import json
z = ”[{‘id’: ‘x’, ‘name’: ‘y’}, {‘id’: ‘p’, ‘name’: ‘q’}]”
list(json.loads(z[1:-1]))
And this works fine for when there is only one stringified dictionary (”[{‘id’: ‘x’, ‘name’: ‘y’}]”) but because the dictionaries have shared keys, they cannot simply be jsonified.
Once this is done, I’ll retrieve the value from name of each and create a list of those.
ANSWERED
Thanks #Tenacious B
To turn the string into the list of the dicts:
import json
z = ”[{‘id’: ‘x’, ‘name’: ‘y’}, {‘id’: ‘p’, ‘name’: ‘q’}]”
data = json.loads(z.replace("'", ""))]) # this will be a list of dicts
Output:
[{'id': 'x', 'name': 'y'}, {'id': 'p', 'name': 'q'}]
And to apply to a pandas dataframe having a column with entries as the above, retrieving only the value from the desired key:
import json
df['col'] = df['col'].apply(lambda x: [i['name'] for i in json.loads(x.replace("'", ""))])
You can have the same keys in different dicts/json objects, also to loads() you need to replace the ' with ":
import json
z = "[{'id': 'x', 'name': 'y'}, {'id': 'p', 'name': 'q'}]"
data = json.loads(z.replace("'", '"')) # this will be a list of dicts
print(data)
Output:
[{'id': 'x', 'name': 'y'}, {'id': 'p', 'name': 'q'}]
After I searched up how to convert a string list to list object I came across this: How to convert string representation of list to a list?
using ast.literal_eval can solve you problem.

Save DataFrame as Json with non unique index

my DF is:
df = pd.DataFrame({'city': ['POA', 'POA', 'SAN'], 'info' : [10,12,5]}, index = [4314902, 4314902, 4300803])
df.index.rename('ID_city', inplace=True)
output:
city info
ID_city
4314902 POA 10
4314902 POA 12
4300803 SAN 5
I need to save as json oriented by index. The following command works only when each index is unique.
df.to_json('df.json', orient='index')
Is possible to save this DataFrame and when he find a duplicate index, create a array?
My desire output:
{ 4314902 : [ {'city': 'POA', 'info': 10} , {'city': 'POA', 'info': 11} ]
,4300803 : {'city': 'SAN', 'info': 5} }
I'm not aware of built-in Pandas functionality, that handles duplicate indexes in json orient='index' exporting.
You could of course build this manually. Merge the columns into one that contains a dict:
cols_as_dict = df.apply(dict, axis=1)
ID_city
4314902 {'city': 'POA', 'info': 10}
4314902 {'city': 'POA', 'info': 12}
4300803 {'city': 'SAN', 'info': 5}
Put rows into lists, grouped by the index:
combined = cols_as_dict.groupby(cols_as_dict.index).apply(list)
ID_city
4300803 [{'city': 'SAN', 'info': 5}]
4314902 [{'city': 'POA', 'info': 10}, {'city': 'POA', ...
Then write the json:
combined.to_json()
'{"4300803":[{"city":"SAN","info":5}],"4314902":[{"city":"POA","info":10},{"city":"POA","info":12}]}'
It creates a list even if there's just a single entry per index. That should make processing actually easier than if you mix the data types (either list of elements or single element).
If you are set on the mixed type (either dict or list of several dicts), then do combined.to_dict(), change the lists with single elements back into their first element, and then dump the json.

Categories