How do I access a specific value in a nested Python dictionary? - python

I am trying to figure out how to filter for the dictionaries that have a status of "awaiting_delivery". I am not sure how to do this (or if it is impossible). I am new to python and programming. I am using Python 3.8.5 on VS Code on Ubuntu 20.04. The data below is sample data that I created that resembles json data from an API. Any help on how to filter for "status" would be great. Thank you.
nested_dict = {
'list_data': [
{
'id': 189530,
'total': 40.05,
'user_data': {
'id': 1001,
'first_name': 'jane',
'last_name': 'doe'
},
'status': 'future_delivery'
},
{
'id': 286524,
'total': 264.89,
'user_data': {
'id': 1002,
'first_name': 'john',
'last_name': 'doe'
},
'status': 'awaiting_delivery'
},
{
'id': 368725,
'total': 1054.98,
'user_data': {
'id': 1003,
'first_name': 'chris',
'last_name': 'nobody'
},
'status': 'awaiting_delivery'
},
{
'id': 422955,
'total': 4892.78,
'user_data': {
'id': 1004,
'first_name': 'mary',
'last_name': 'madeup'
},
'status': 'future_delivery'
}
],
'current_page': 1,
'total': 2,
'first': 1,
'last': 5,
'per_page': 20
}
#confirm that nested_dict is a dictionary
print(type(nested_dict))
#create a list(int_list) from the nested_dict dictionary
int_list = nested_dict['list_data']
#confirm that int_list is a list
print(type(int_list))
#create the int_dict dictionary from the int_list list
for int_dict in int_list:
print(int_dict)
#this is my attempt at filtering the int_dict dictionar for all orders with a status of awaiting_delivery
for order in int_dict:
int_dict.get('status')
print(order)
Output from Terminal Follows:
<class 'dict'>
<class 'list'>
{'id': 189530, 'total': 40.05, 'user_data': {'id': 1001, 'first_name': 'jane', 'last_name': 'doe'}, 'status': 'future_delivery'}
{'id': 286524, 'total': 264.89, 'user_data': {'id': 1002, 'first_name': 'john', 'last_name': 'doe'}, 'status': 'awaiting_delivery'}
{'id': 368725, 'total': 1054.98, 'user_data': {'id': 1003, 'first_name': 'chris', 'last_name': 'nobody'}, 'status': 'awaiting_delivery'}
{'id': 422955, 'total': 4892.78, 'user_data': {'id': 1004, 'first_name': 'mary', 'last_name': 'madeup'}, 'status': 'future_delivery'}
id
total
user_data
status

You can obtain a filtered list of dicts by doing conditional list comprehension on your list of dicts:
# filter the data
list_data_filtered = [entry for entry in nested_dict['list_data']
if entry['status'] == 'awaiting_delivery']
# print out the results
for entry in list_data_filtered:
print(entry)
# results
# {'id': 286524, 'total': 264.89, 'user_data': {'id': 1002, 'first_name': 'john', 'last_name': 'doe'}, 'status': 'awaiting_delivery'}
# {'id': 368725, 'total': 1054.98, 'user_data': {'id': 1003, 'first_name': 'chris', 'last_name': 'nobody'}, 'status': 'awaiting_delivery'}

Related

How get extract unique dictionary from list of dictionary with preference of value

I have dictionary below
test = [ { 'id': '195', 'Name': 'i', 'Email': 'chdtn#gmail.com', 'role': 'Product' },
{ 'id': '219', 'Name': 'umar', 'Email': 'ddhi#gmail.com', 'role': 'Product' },
{ 'id': '74', 'Name': 'Are', 'Email': 'ddhit#gmail.com', 'role': 'Tester' },
{ 'id': '24', 'Name': 'Mee', 'Email': 'huul#gmail.com', 'role': 'Tester' },
{ 'id': '230', 'Name': 'abc', 'Email': 'deyan#gmail.com', 'role': 'Tester' },
{ 'id': '220', 'Name': 'Sc', 'Email': 'deyan#gmail.com', 'role': 'Product' },
{ 'id': '230', 'Name': 'Sn', 'Email': 'deyan#gmail.com', 'role': 'Tester' } ]
I need to extract unique email from above list dict
I need to give give role preference Product then to Tester
My Code is below
dict([(d['Email'], d) for d in test]).values()
My Out:
dict_values([{'id': '195', 'Name': 'i', 'Email': 'chdtn#gmail.com', 'role': 'Product'},
{'id': '219', 'Name': 'umar', 'Email': 'ddhi#gmail.com', 'role': 'Product'},
{'id': '74', 'Name': 'Are', 'Email': 'ddhit#gmail.com', 'role': 'Tester'},
{'id': '24', 'Name': 'Mee', 'Email': 'huul#gmail.com', 'role': 'Tester'},
{'id': '230', 'Name': 'Sn', 'Email': 'deyan#gmail.com', 'role': 'Tester'}])
Here in my out
{'id': '230', 'Name': 'Sn', 'Email': 'deyan#gmail.com', 'role': 'Tester'}
has to replace with
{ 'id': '220', 'Name': 'Sc', 'Email': 'deyan#gmail.com', 'role': 'Product' }
because "Product" have higher preference.
How to update my code? dict([(d['Email'], d) for d in test]).values()
Here is in case you would like to insist on using dictionaries.
We go from one row to another. Check if the email is already in the new dictionary as key.
If not, we add this as a new one.
If so, we check our new row. If our new role is "product", we will delete what was already in the dictionary, and add the new row.
new_dict = {}
for row in test:
if row["Email"] not in new_dict.keys():
new_dict.update({row["Email"]: row})
else:
if row["role"]=="Product":
new_dict.pop(row["Email"])
new_dict.update({row["Email"]: row})
Perhaps you could try it with two loops; once to get the unique emails, and second time to make sure to prioritize "Product".
It wasn't clear what happens if there is no "Product" for duplicate "Emails", so in the loop below, the first email is selected in that case.
tmp = {}
for d in test:
tmp.setdefault(d['Email'], []).append(d)
out = []
for k, lst in tmp.items():
if len(lst) == 1:
out.append(lst[0])
else:
for d in lst:
if d['role'] == 'Product':
out.append(d)
break
else:
out.append(lst[0])
Output:
[{'id': '195', 'Name': 'i', 'Email': 'chdtn#gmail.com', 'Account': 'Product'},
{'id': '219', 'Name': 'umar', 'Email': 'ddhi#gmail.com', 'Account': 'Product'},
{'id': '74', 'Name': 'Are', 'Email': 'ddhit#gmail.com', 'role': 'Tester'},
{'id': '24', 'Name': 'Mee', 'Email': 'huul#gmail.com', 'role': 'Tester'},
{'id': '220', 'Name': 'Sc', 'Email': 'deyan#gmail.com', 'role': 'Product'}]
Make it to a data frame and drop_duplicates by Email after sorting the column role.
test = [ { 'id': '195', 'Name': 'i', 'Email': 'chdtn#gmail.com', 'role': 'Product' },
{ 'id': '219', 'Name': 'umar', 'Email': 'ddhi#gmail.com', 'role': 'Product' },
{ 'id': '74', 'Name': 'Are', 'Email': 'ddhit#gmail.com', 'role': 'Tester' },
{ 'id': '24', 'Name': 'Mee', 'Email': 'huul#gmail.com', 'role': 'Tester' },
{ 'id': '230', 'Name': 'abc', 'Email': 'deyan#gmail.com', 'role': 'Tester' },
{ 'id': '220', 'Name': 'Sc', 'Email': 'deyan#gmail.com', 'role': 'Product' },
{ 'id': '230', 'Name': 'Sn', 'Email': 'deyan#gmail.com', 'role': 'Tester' } ]
df = pd.DataFrame(test)
df1 = df.sort_values(by = ["Email", "role"], ascending = True)
res_df = df1.drop_duplicates(["Email"])
output_list = []
for i in res_df.values :
output_list.append(dict([("id", i[0]), ("Name", i[1]), ("Email", i[2]), ("role", i[3])]))
> output_list
[{'id': '195', 'Name': 'i', 'Email': 'chdtn#gmail.com', 'role': 'Product'},
{'id': '219', 'Name': 'umar', 'Email': 'ddhi#gmail.com', 'role': 'Product'},
{'id': '74', 'Name': 'Are', 'Email': 'ddhit#gmail.com', 'role': 'Tester'},
{'id': '220', 'Name': 'Sc', 'Email': 'deyan#gmail.com', 'role': 'Product'},
{'id': '24', 'Name': 'Mee', 'Email': 'huul#gmail.com', 'role': 'Tester'}]

Python steamlit select box menu returns string, but I need dict or list

Stack on this case, Python steamlit select box menu returns string, but I need dict or list, to use it further in my code.
I want to see company1, company2, company3 in dropdown menu, and if user's choice was for example 'company2' get ['ID': 'zxc222’, 'NAME': 'company2','DESC': 'comp2'].
BaseObject = [{
'ID': 'zxc123',
'NAME': 'company1',
'DESC': 'comp1'
}, {
'ID': 'zxc222',
'NAME': 'company2',
'DESC': 'comp2'
}, {
'ID': 'zxc345',
'NAME': 'company3',
'DESC': 'comp3'
}]
lenbo = len(BaseObject)
options = []
for i in range(0, lenbo):
options.append((BaseObject[i])['NAME'])
st.selectbox('Subdivision:', options)
You can do the conversion to a dict after the selectbox:
import streamlit as st
BaseObject = [{
'ID': 'zxc123',
'NAME': 'company1',
'DESC': 'comp1'
}, {
'ID': 'zxc222',
'NAME': 'company2',
'DESC': 'comp2'
}, {
'ID': 'zxc345',
'NAME': 'company3',
'DESC': 'comp3'
}]
lenbo = len(BaseObject)
options = []
for i in range(0, lenbo):
options.append((BaseObject[i])['NAME'])
choice = st.selectbox('Subdivision:', options)
chosen_base_object = None
for base_object in BaseObject:
if base_object["NAME"] == choice:
chosen_base_object = dict(base_object)
print(chosen_base_object) # {'ID': 'zxc345', 'NAME': 'company3', 'DESC': 'comp3'}

How to rename keys in a dictionary and make a dataframe of it?

I have a complex situation which I hope to solve and which might profit us all. I collected data from my API, added a pagination and inserted the complete data package in a tuple named q1 and finally I have made a dictionary named dict_1of that tuple which looks like this:
dict_1 = {100: {'ID': 100, 'DKSTGFase': None, 'DK': False, 'KM': None,
'Country: {'Name': GE', 'City': {'Name': 'Berlin'}},
'Type': {'Name': '219'}, 'DKObject': {'Name': '8555', 'Object': {'Name': 'Car'}},
'Order': {'OrderId': 101, 'CreatedOn': '2018-07-06T16:54:36.783+02:00',
'ModifiedOn': '2018-07-06T16:54:36.783+02:00',
'Name': Audi, 'Client': {‘1’ }}, 'DKComponent': {'Name': ‘John’}},
{200: {'ID': 200, 'DKSTGFase': None, 'DK': False, ' KM ': None,
'Country: {'Name': ES', 'City': {'Name': 'Madrid'}}, 'Type': {'Name': '220'},
'DKObject': {'Name': '8556', 'Object': {'Name': 'Car'}},
'Order': {'OrderId': 102, 'CreatedOn': '2018-07-06T16:54:36.783+02:00',
'ModifiedOn': '2018-07-06T16:54:36.783+02:00',
'Name': Mercedes, 'Client': {‘2’ }}, 'DKComponent': {'Name': ‘Sergio’}},
Please note that in the above dictionary I have just stated 2 records. The actual dictionary has 1400 records till it reaches ID 1500.
Now I want to 2 things:
I want to change some keys for all the records. key DK has to become DK1. Key Name in Country has to become Name1 and Name in Object has to become 'Name2'
The second thing I want is to make a dataFrame of the whole bunch of data. My expected outcome is:
This is my code:
q1 = response_2.json()
next_link = q1['#odata.nextLink']
q1 = [tuple(q1.values())]
while next_link:
new_response = requests.get(next_link, headers=headers, proxies=proxies)
new_data = new_response.json()
q1.append(tuple(new_data.values()))
next_link = new_data.get('#odata.nextLink', None)
dict_1 = {
record['ID']: record
for tup in q1
for record in tup[2]
}
#print(dict_1)
for x in dict_1.values():
x['DK1'] = x['DK']
x['Country']['Name1'] = x['Country']['Name']
x['Object']['Name2'] = x['Object']['Name']
df = pd.DataFrame(dict_1)
When i run this I receive the following Error:
Traceback (most recent call last):
File "c:\data\FF\Desktop\Python\PythongMySQL\Talky.py", line 57, in <module>
x['Country']['Name1'] = x['Country']['Name']
TypeError: 'NoneType' object is not subscriptable
working code
lists=[]
alldict=[{100: {'ID': 100, 'DKSTGFase': None, 'DK': False, 'KM': None,
'Country': {'Name': 'GE', 'City': {'Name': 'Berlin'}},
'Type': {'Name': '219'}, 'DKObject': {'Name': '8555', 'Object': {'Name': 'Car'}},
'Order': {'OrderId': 101, 'CreatedOn': '2018-07-06T16:54:36.783+02:00',
'ModifiedOn': '2018-07-06T16:54:36.783+02:00',
'Name': 'Audi', 'Client': {'1' }}, 'DKComponent': {'Name': 'John'}}}]
for eachdict in alldict:
key=list(eachdict.keys())[0]
eachdict[key]['DK1']=eachdict[key]['DK']
del eachdict[key]['DK']
eachdict[key]['Country']['Name1']=eachdict[key]['Country']['Name']
del eachdict[key]['Country']['Name']
eachdict[key]['DKObject']['Object']['Name2']=eachdict[key]['DKObject']['Object']['Name']
del eachdict[key]['DKObject']['Object']['Name']
lists.append([key, eachdict[key]['DK1'], eachdict[key]['KM'], eachdict[key]['Country']['Name1'],
eachdict[key]['Country']['City']['Name'], eachdict[key]['DKObject']['Object']['Name2'], eachdict[key]['Order']['Client']])
pd.DataFrame(lists, columns=[<columnNamesHere>])
Output:
{100: {'ID': 100,
'DKSTGFase': None,
'KM': None,
'Country': {'City': {'Name': 'Berlin'}, 'Name1': 'GE'},
'Type': {'Name': '219'},
'DKObject': {'Name': '8555', 'Object': {'Name2': 'Car'}},
'Order': {'OrderId': 101,
'CreatedOn': '2018-07-06T16:54:36.783+02:00',
'ModifiedOn': '2018-07-06T16:54:36.783+02:00',
'Name': 'Audi',
'Client': {'1'}},
'DKComponent': {'Name': 'John'},
'DK1': False}}

converting list to dictionary in a python

I have a data in a list like below:
[
{'id': 1, 'first_name': 'Jeanette', 'last_name': 'Penddreth', 'email': 'jpenddreth0#census.gov', 'gender': 'Female', 'ip_address': '26.58.193.2'},
{'id': 2, 'first_name': 'Giavani', 'last_name': 'Frediani', 'email': 'gfrediani1#senate.gov', 'gender': 'Male', 'ip_address': '229.179.4.212'},
{'id': 3, 'first_name': 'Noell', 'last_name': 'Bea', 'email': 'nbea2#imageshack.us', 'gender': 'Female', 'ip_address': '180.66.162.255'},
{'id': 4, 'first_name': 'Willard', 'last_name': 'Valek', 'email': 'wvalek3#vk.com', 'gender': 'Male', 'ip_address': '67.76.188.26'}
]
I am loading the data into the dynamoDb. It is failing with the error type: <class 'list'>, valid types: <class 'dict'>: ParamValidationError.
How do I convert the above list into a dictionary?
EDIT Code used:
import boto3
import json
s3_client=boto3.client('s3')
dynamodb=boto3.resource('dynamodb')
def lambda_handler(event, context):
bucket=event['Records'][0]['s3']['bucket']['name']
json_filename=event['Records'][0]['s3']['object']['key']
json_object=s3_client.get_object(Bucket=bucket,Key=json_filename)
jsonFileReader=json_object['Body'].read()
jsonDictionary=json.loads(jsonFileReader)
table=dynamodb.Table('EMPLOYEE_DETAILS')
table.put_item(Item=jsonDictionary)
return 'Done'
I'm not familiar with dynamodb, but I imagine this will work. If your JSON is a list, then you need to iterate through the items in your list, adding each one to the table.
Replace the line:
table.put_item(Item=jsonDictionary)
with:
if type(jsonDictionary) == type([]):
# It is a list - iterate through it
for item in jsonDictionary:
table.put_item(Item=item)
else:
table.put_item(Item=jsonDictionary)

How to build a recursive dictionary tree from an ordered adjacency list

I've been trying to figure this out all day and Im at my wits end. Maybe I'm just getting to old for this.
I'm trying to build a tree for the load_bulk feature on django-treebeard as specified here
To save you looking, it should look like this:
data = [{'data':{'desc':'1'}},
{'data':{'desc':'2'}, 'children':[
{'data':{'desc':'21'}},
{'data':{'desc':'22'}},
{'data':{'desc':'23'}, 'children':[
{'data':{'desc':'231'}},
]},
{'data':{'desc':'24'}},
]},
{'data':{'desc':'3'}},
{'data':{'desc':'4'}, 'children':[
{'data':{'desc':'41'}},
]},
]
'data' holds the record, and if it has children, 'children' is a list of more 'data' dicts (that can also contain a list of children and so on recursively)
I get the data as an ordered list (ordered as in depth first, not by id):
e.g:
[
{'id': 232, 'name': 'jon', 'parent': 'None'}
{'id': 3522, 'name': 'dave', 'parent': '232'}
{'id': 2277, 'name': 'alice', 'parent': '3522'}
{'id': 119, 'name': 'gary', 'parent': '232'}
{'id': 888, 'name': 'gunthe', 'parent': '119'}
{'id': 750, 'name': 'beavis', 'parent': 'None'}
{'id': 555, 'name': 'urte', 'parent': '750'}
]
How can I transform it into a treebeard compliant dictionary that would look like this (typo's excepted):
[
{'data': {'id': 232, 'name': 'jon', 'parent': 'None'},
'children': [
{'data': {'id': 3522, 'name': 'dave', 'parent': '232'},
'children': [
{'data': {'id': 2277, 'name': 'alice', 'parent': '3522'}}
]
}
{'data': {'id': 119, 'name': 'gary', 'parent': '232'},
'children': [
{'id': 888, 'name': 'gunthe', 'parent': '119'}
]
}
]
{'data': {'id': 750, 'name': 'beavis', 'parent': 'None'},
'children': [
{'id': 555, 'name': 'urte', 'parent': '750'}
]
}
]
I guess I need some kind of recursion function seeing as its a recursive structure but all my attempts have failed. My brain doesnt do recursion so good.
I did a lot of searching and found mostly solutions pertaining to lists or other structures that i cant mould to fit. I'm a relative noob. ps i had more fun manually typing out the example than i did the rest of day (apart from dinner time).
Maybe there are better ways, but here is one solution:
users = [
{
'id': 232,
'name': 'jon',
'parent': None
},
{
'id': 3522,
'name': 'dave',
'parent': 232
},
{
'id': 2277,
'name': 'alice',
'parent': 3522
},
{
'id': 119,
'name': 'gary',
'parent': 232
},
{
'id': 888,
'name': 'gunthe',
'parent': 119
},
{
'id': 750,
'name': 'beavis',
'parent': None
},
{
'id': 555,
'name': 'urte',
'parent': 750
}
]
users_map = {}
for user in users:
users_map[user['id']] = user
users_tree = []
for user in users:
if user['parent'] is None:
users_tree.append(user)
else:
parent = users_map[user['parent']]
if 'childs' not in parent:
parent['childs'] = []
parent['childs'].append(user)
print(users_tree)
#user as {data: user, childs: []}
users_map = {}
for user in users:
users_map[user['id']] = {'data': user, 'childs': []}
users_tree = []
for user in users:
if user['parent'] is None:
users_tree.append(users_map[user['id']])
else:
parent = users_map[user['parent']]
parent['childs'].append(users_map[user['id']])
print(users_tree)

Categories

Resources