Create a key in a nested dict without using update function - python

Input :
{'Name': 'A','Blood Group': 'O +ve', 'Age': '1', 'Sex': 'M','Phone Number': '01234567', 'Mobile Number': '9876543210', 'Date of Birth': '01-01-95'}
1.
d.update({'Contact Info': {'Mobile Number':d['Mobile Number'],'Phone
Number':d['Phone Number'] }})
2.
d['Contact Info']={}
d['Contact Info']['Mobile Number']=d['Mobile Number']
Can you say any better way or different way to create a dictionary key which can be assigned to a dict item as value???
Original Code:
import csv
import copy
from collections import namedtuple
d={}
ls=[]
def nest():
with open ("details.csv", 'r') as f:
reader=csv.DictReader(f)
for row in reader:
d.update(row)
PersonalDetails = namedtuple('PersonalDetails','blood_group age sex')
ContactInfo = namedtuple('ContactInfo','phone_number mobile_number')
d1=copy.deepcopy(d)
ls.append(d1)
print ls
nest()

This is how I would update my dict of dicts:
I would create a function that will take a 3 arguments(The key of the subdict, the subkey of said subdict and the value you want to change.) I assign to be updated and then update that value.
d = {
'Name': 'A',
'Personal Details': {'Blood Group': 'O +ve', 'Age': '1', 'Sex': 'M'},
'Contact Info': {'Phone Number': '01234567', 'Mobile Number': '9876543210'},
'Date of Birth': '01-01-95'
}
def updateInfo(toBeUpdated, subkey, ValueToUpdate):
if toBeUpdated in d:
tempdict = d[toBeUpdated]
tempdict[subkey] = ValueToUpdate
d[toBeUpdated] = tempdict
print (d)
else:
print ("No %s to update" % (toBeUpdated))
updateInfo('Contact Info','Mobile Number','999 999 9999')
the result I get from this:
{'Name': 'A', 'Personal Details': {'Blood Group': 'O +ve', 'Age': '1', 'Sex': 'M'}, 'Contact Info': {'Phone Number': '01234567', 'Mobile Number': '999 999 9999'}, 'Date of Birth': '01-01-95'}

Related

How to remove the duplicate dictionaries from the list of dictionaries where dictionary contains an another dictionary? [duplicate]

This question already has answers here:
Remove duplicate dict in list in Python
(16 answers)
Closed 8 months ago.
I have a bit complex list of dictionaries which looks like
[
{'Name': 'Something XYZ', 'Address': 'Random Address', 'Customer Number': '-', 'User Info': [{'Registration Number': '17002', 'First Name': 'John', 'Middle Name': '', 'Last Name': 'Denver'}, {'Registration Number': '27417', 'First Name': 'Robert', 'Middle Name': '', 'Last Name': 'Patson'}]},
{'Name': 'Something XYZ', 'Address': 'Random Address', 'Customer Number': '-', 'User Info': [{'Registration Number': '27417', 'First Name': 'Robert', 'Middle Name': '', 'Last Name': 'Patson'}, {'Registration Number': '17002', 'First Name': 'John', 'Middle Name': '', 'Last Name': 'Denver'}]}
]
Expected is below
[
{'Name': 'Something XYZ', 'Address': 'Random Address', 'Customer Number': '-', 'User Info': [{'Registration Number': '17002', 'First Name': 'John', 'Middle Name': '', 'Last Name': 'Denver'}, {'Registration Number': '27417', 'First Name': 'Robert', 'Middle Name': '', 'Last Name': 'Patson'}]},
]
I want to remove the duplicate dictionaries in this list but I don't know how to deal with User Info because the order of the items might be different. A duplicate case would be where all the dictionary items are exactly the same and in the case of User Info order doesn't matter.
I think the best way is to make a hash of User Info by sum the hash values of it's elements (sum will tolerate position change).
def deepHash(value):
if type(value) == list:
return sum([deepHash(x) for x in value])
if type(value) == dict:
return sum([deepHash(x) * deepHash(y) for x, y in value.items()])
return hash(str(value))
and you can simply check the hash of you inputs:
assert deepHash({"a": [1,2,3], "c": "d"}) == deepHash({"c": "d", "a": [3,2,1]})

Is there a way to extract the selected value in a nested Dictionary using a for loop?

Using this dictionary, is there a way I can only extract the Name, Last Name, and Age of the boys?
myDict = {'boy1': {'Name': 'JM', 'Last Name':'Delgado', 'Middle Name':'Goneza', 'Age':'21',
'Birthday':'8/22/2001', 'Gender':'Male'},
'boy2': {'Name': 'Ralph', 'Last Name':'Tubongbanua', 'Middle Name':'Castro',
'Age':'21', 'Birthday':'9/5/2001', 'Gender':'Male'},}
for required in myDict.values():
print (required ['Name', 'Last Name', 'Age'])
The output is:
JM
Ralph
What I have in mind is
JM Delgado 21
Ralph Tubongbanua 21
You have to extract the keys one by one:
myDict = {'boy1': {'Name': 'JM', 'Last Name':'Delgado', 'Middle Name':'Goneza', 'Age':'21',
'Birthday':'8/22/2001', 'Gender':'Male'},
'boy2': {'Name': 'Ralph', 'Last Name':'Tubongbanua', 'Middle Name':'Castro',
'Age':'21', 'Birthday':'9/5/2001', 'Gender':'Male'},}
for required in myDict.values():
print (required['Name'], required['Last Name'],required['Age'])
this could be a solution:
myDict = {'boy1': {'Name': 'JM', 'Last Name':'Delgado', 'Middle, Name':'Goneza', 'Age':'21', 'Birthday':'8/22/2001', 'Gender':'Male'},
'boy2': {'Name': 'Ralph', 'Last Name':'Tubongbanua', 'Middle Name':'Castro',
'Age':'21', 'Birthday':'9/5/2001', 'Gender':'Male'},}
for required in myDict.values():
print(required ['Name'], required['Last Name'], required['Age'])
When printing multiple values separated with commas, a space will automatically appear between them.

Assign values from list to dictionary without for loop in Python

I need the same output by not using any loops.
I have two lists:
groupVal = ["Staff 1","Staff 2"]
nameValue = ["ABC","XYZ"]
My code looks like this:
sdict = {"group": {}}
for index, item in enumerate(groupVal):
sdict ['group'][item] = {"name": "Hi "+nameValue[index], "approval" :"yes"}
Output for sdict:
{'group': {'Staff 1': {'name': 'Hi ABC', "approval" :"yes"}, 'Staff 2': {'name': 'Hi XYZ', "approval" :"yes"}}}
Even better, a one liner for the whole sdict
groupVal = ["Staff 1","Staff 2"]
nameValue = ["ABC","XYZ"]
sdict = {'group': {item: {'name': 'Hi ' + value, 'approval': 'yes'} for item, value in zip(groupVal, nameValue)}}
sdict
{'group': {
'Staff 1': {'name': 'Hi ABC', 'approval': 'yes'},
'Staff 2': {'name': 'Hi XYZ', 'approval': 'yes'}
}
}

How to merge the multiple lists into a dict with Python?

I'm using Python to translate a txt file into JSON. However, when I was iterating the lines from txt, the result is containing multiple lists there, and I failed to merge the list into a dict with the function zip(). Can anyone help me figure it out? I've been stuck here for a couple of hours. Thanks.
with open(path, encoding='utf-8-sig') as f:
seq = re.compile("[|]")
for line_num, line in enumerate(f.readlines()):
result = seq.split(line.strip("\n"))
print(result)
This is the output:
['Delivery', 'Customer Name', 'Shipment Priority', 'Creation Date', 'Customer Number', 'Batch Name', 'Release Date']
['69328624', 'Zhidi Feng', 'Standard Priority', '13-OCT-20', '432579', '19657423', '13-OCT-20 00:01:07']
['69328677', 'Zhengguo Huang', 'Standard Priority', '13-OCT-20', '429085', '19657425', '13-OCT-20 00:01:34']
Something like that ?
>>> lists = [["12", "Abc", "def"], ["34", "Ghi", "jkl"]]
>>> fields = ["id", "lastname", "firstname"]
>>> dicts = []
>>> for l in lists:
... d = {}
... for i in range(3):
... d[fields[i]] = l[i]
... dicts.append(d)
>>> dicts
[{'id': '12', 'lastname': 'Abc', 'firstname': 'def'},
{'id': '34', 'lastname': 'Ghi', 'firstname': 'jkl'}]
Edit: included in your existing code:
dicts = []
for line_num, line in enumerate(f.readlines()):
result = seq.split(line.strip("\n"))
if line_num = 0:
keys = result
else:
d = {}
for i, key in enumerate(keys):
d[key] = result[i]
dicts.append(d)
(I didn't test this since I don't have the file you're using)
you can use zip for making a dictionary like this. (I separate keys and values in two lists.)
with open(path, encoding='utf-8-sig') as f:
seq = re.compile("[|]")
lines = f.readlines()
keys = lines[0] # stting keys
dict_list = []
for line_num, line in enumerate(lines[1:]):
result = seq.split(line.strip("\n"))
dict_list.append(dict(zip(keys, result))) # making a dict and append it to list
>>> total
[['Delivery', 'Customer Name', 'Shipment Priority', 'Creation Date', 'Customer Number', 'Batch Name', 'Release Date'], ['69328624', 'Zhidi Feng', 'Standard Priority', '13-OCT-20', '432579', '19657423', '13-OCT-20 00:01:07'], ['69328677', 'Zhengguo Huang', 'Standard Priority', '13-OCT-20', '429085', '19657425', '13-OCT-20 00:01:34']]
>>> keys = total[0]
>>>
>>> values = total[1:]
>>> wanted = [ dict(zip(keys, value)) for value in values]
>>> wanted
[{'Delivery': '69328624', 'Customer Name': 'Zhidi Feng', 'Shipment Priority': 'Standard Priority', 'Creation Date': '13-OCT-20', 'Customer Number': '432579', 'Batch Name': '19657423', 'Release Date': '13-OCT-20 00:01:07'}, {'Delivery': '69328677', 'Customer Name': 'Zhengguo Huang', 'Shipment Priority': 'Standard Priority', 'Creation Date': '13-OCT-20', 'Customer Number': '429085', 'Batch Name': '19657425', 'Release Date': '13-OCT-20 00:01:34'}]

How to count how many times a specific value in a dictionary of dictionaries in Python 3

I know there must be a very simple solution to this question but I am new with Python and cannot figure out how to do it.
All I simply want to do is count how many times a particular value appears in this dictionary, for example, how many males there are.
people = {}
people['Applicant1'] = {'Name': 'David Brown',
'Gender': 'Male',
'Occupation': 'Office Manager',
'Age': '33'}
people['Applicant2'] = {'Name': 'Peter Parker',
'Gender': 'Male',
'Occupation': 'Postman',
'Age': '25'}
people['Applicant3'] = {'Name': 'Patricia M',
'Gender': 'Female',
'Occupation': 'Teacher',
'Age': '35'}
people['Applicant4'] = {'Name': 'Mark Smith',
'Gender': 'Male',
'Occupation': 'Unemployed',
'Age': '26'}
Any help is much appreciated!
For your example, you have applicants and their data. The data you are checking is their gender, so the below code will accomplish that.
amount = 0 # amount of people matching condition
for applicant in people.values(): # looping through all applicants
if applicant.get('Gender', False) == 'Male': # checks if applicant['Gender'] is 'Male'
# note it will return False if ['Gender'] wasn't set
amount += 1 # adds matching people to amount
This will get the amount of males in the applicant list.
I'd suggest refactoring your logic a bit to use a list of dicts.
people = [
{
'Name': 'David Brown',
'Gender': 'Male',
'Occupation': 'Office Manager',
'Age': '33'
},
{
'Name': 'Peter Parker',
'Gender': 'Male',
'Occupation': 'Postman',
'Age': '25'
},
{
'Name': 'Patricia M',
'Gender': 'Female',
'Occupation': 'Teacher',
'Age': '35'
},
{
'Name': 'Mark Smith',
'Gender': 'Male',
'Occupation': 'Unemployed',
'Age': '26'
}
]
Then you can use logic like
[applicant for applicant in people if applicant['Gender'] == 'Male']
Which will give you all of the males in the list
This is a function to count the number of occurrences of a given value inside a dictionary:
def count(dic, val):
sum = 0
for key,value in dic.items():
if value == val:
sum += 1
if type(value) is dict:
sum += count(dic[key], val)
return sum
Then you can use it as follow:
result = count(people, 'Male')

Categories

Resources