Reputation: 143
I have a csv file which contains details of 3 persons name,date of birth,age,sex.blood group, mobile number, phone number. I would like to write those csv details into a nested dict which works when i print d in line 20 but the dict is unordered (i.e) Details of 1st person is in different order when compared to others. I would like to print them as nested dict and also append them to an empty list so that I can get the list by iterating the dict values.
Input:
Name Age Date of birth Sex Blood Group Mobile number Phone number
A 1 01-01-95 M O +ve 9876543210 01234567
B 2 02-02-99 F B +ve 9898989898 07854123
C 3 03-03-93 F A +ve 9123456780 04693218
Here are my codes:
import csv
d={}
ls=[]
def nest():
with open ("details.csv", 'r') as f:
reader=csv.DictReader(f)
for row in reader:
d.update(row)
d.update({'Contact Info': {'Mobile Number':d['Mobile Number'],'Phone Number':d['Phone Number']}})
d.update({'Personal Details': {'Sex':d['Sex'], 'Blood Group':d['Blood Group'], 'Age':d['Age']}})
map(d.pop, ['Mobile Number','Phone Number','Sex','Blood Group', 'Age'])
print d
ls.append(d)
print ls
nest()
Output:
[{'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'}
{'Name': 'B','Personal Details': {'Blood Group': 'B +ve', 'Age': '2', 'Sex': 'F'}, 'Contact Info': {'Phone Number': '07854123', 'Mobile Number': '9898989898'}, 'Date of Birth': '02-02-99'}
{'Name': 'C','Personal Details': {'Blood Group': 'A +ve', 'Age': '3', 'Sex': 'F'}, 'Contact Info': {'Phone Number': '04693218', 'Mobile Number': '9123456780'}, 'Date of Birth': '03-03-93'}]
Upvotes: 0
Views: 324
Reputation: 4712
I think your update logic is a bit twisted, since you are always updating the same dictionary you are actually overriding the previous values you appended to ls
.
So if you want to keep your code as is (which I don't recommend) you need to copy the dict before appending it. ls.append(deepcopy(d))
Dicts are mutable types and you always append the same reference to the list, so all elements will have the same value (the last row).
Since you want the keys to be ordered, just use and OrderedDict
I did it in one line just for the golf, but it's roughly how I'd go about it:
def nest(reader):
return [
OrderedDict(
[
('Name', row['Name']),
('Personal Details', OrderDicted((k, row[k]) for k in ('Sex', 'Blood Group', 'Age'))),
('Contact Info', OrderedDict((k, row[k]) for k in ('Mobile Number', 'Phone Number'))),
('Date of Birth', row[k])
]
) for row in reader
]
Edit Also if you are using python 3.6 and your keys are ordered it is just a side effect of the new implementation that should not be relied upon, see this discussion
Upvotes: 1