I am working on a project and need to make use of UserDict instead of dict. I am importing a JSON file that is a dictionary with lists containing more dictionaries.
Here is some example code and the behavior differences I am seeing:
JavaScript
x
37
37
1
import json
2
from collections import UserDict
3
import pprint
4
5
person_string = '{"name" : "Bob",
6
"age" : 25,
7
"addresses":[{"city" : "Greenville", "state" : "NC" },
8
{"city" : "Whiteville", "state" : "NC" }]}'
9
10
# dict Example
11
person_dict = json.loads(person_string)
12
addresses = person_dict['addresses']
13
addr_1 = addresses[0]
14
print(addr_1)
15
print("n")
16
17
# Add street to the first city entry
18
addr_1['street'] = "123 The Road"
19
print(addr_1)
20
print("n")
21
pprint.pprint(person_dict)
22
23
print("n")
24
25
# UserDict Example
26
person_user_dict = UserDict(json.loads(person_string))
27
user_addresses = person_user_dict['addresses']
28
user_addr_1 = UserDict(user_addresses[0])
29
print(user_addr_1)
30
print("n")
31
32
# Add street to the first city entry
33
user_addr_1['street'] = "123 The Road"
34
print(user_addr_1)
35
print("n")
36
pprint.pprint(person_user_dict)
37
The output:
JavaScript
1
21
21
1
# Dictionary Example
2
{'city': 'Greenville', 'state': 'NC'}
3
4
{'city': 'Greenville', 'state': 'NC', 'street': '123 The Road'}
5
6
{'name': 'Bob',
7
'age': 25,
8
'addresses': [{'city': 'Greenville', 'state': 'NC', 'street': '123 The Road'},
9
{'city': 'Whiteville', 'state': 'NC'}]}
10
11
# UserDict Example
12
{'city': 'Greenville', 'state': 'NC'}
13
14
{'city': 'Greenville', 'state': 'NC', 'street': '123 The Road'}
15
16
17
{'name': 'Bob',
18
'age': 25,
19
'addresses': [{'city': 'Greenville', 'state': 'NC'}, <---- The 'street' is missing
20
{'city': 'Whiteville', 'state': 'NC'}]}
21
Why did the new key not get added to person_user_dict and how can I get UserDict to behave the same way as a dictionary?
Advertisement
Answer
Because you created a new dictionary here:
JavaScript
1
2
1
user_addr_1 = UserDict(user_addresses[0])
2
This isn’t unexpected at all, indeed, this is how dict
works. You would see the same exact behavior if you did:
JavaScript
1
2
1
user_addr_1 = dict(user_addresses[0])
2
You would need to recursively convert all the dict’s to UserDict
objects instead. But actually, you just want to use the object_pairs_hook
for the json decoder:
JavaScript
1
19
19
1
In [3]: import json
2
from collections import UserDict :
3
:
4
person_string = '{"name" : "Bob", :
5
"age" : 25, :
6
"addresses":[{"city" : "Greenville", "state" : "NC" }, :
7
"city" : "Whiteville", "state" : "NC" }]}' : {
8
9
In [4]: person_dict = json.loads(person_string, object_pairs_hook=UserDict)
10
11
In [5]: person_dict
12
Out[5]: {'name': 'Bob', 'age': 25, 'addresses': [{'city': 'Greenville', 'state': 'NC'}, {'city': 'Whiteville', 'state': 'NC'}]}
13
14
In [6]: type(person_dict)
15
Out[6]: collections.UserDict
16
17
In [7]: type(person_dict['addresses'][0])
18
Out[7]: collections.UserDict
19