Reputation: 1932
I'm reading a json file with the structure below:
[{"id":1,"gender":"Male","first_name":"Andrew","last_name":"Scott","email":"[email protected]","ville":"Connecticut"},
{"id":3,"first_name":"Mary","last_name":"Richards","email":"[email protected]","ville":"Minnesota"}]
So, as you can see in the second "line" the field "gender" it'is not present.I realize that because my code to read the file got wrong in this line.
my code:
import json
def jsonreader():
##Reader for json files
##Open files using json library
with open('cust_data.json') as file:
data = json.load(file)
resultlist = list()
for line in data:
print(line["id"],line["gender"])
I got the error:-
C:/xxxxx/x.py
1 Male
Traceback (most recent call last):
2 Female
File "C:/xxxxx/x", line 67, in <module>
jsonreader()
File "C:/xxxxx/x", line 56, in jsonreader
print(line["id"],line["gender"])
KeyError: 'gender'
Before answer guys, you should know that I have a method to define the default value in "gender", voila my method:
def definegender(x):
if x is None:
x = 'unknown'
return x
elif (x =='Male') or (x=='Female'):#not None:
return {
'Male':'M',
'Female': 'F'
}.get(x)
else:
return x
So, in this case, I could not use something like a default value reading the values because I need to send some value to my method.
Some one of you guys would know how should be the best way to read this kind of files when we have missing objects. Thanks
Upvotes: 4
Views: 2833
Reputation: 18916
Although this already has a perfect answer, my point of view is that there can be alternatives too. So here it is:
for line in data:
try:
print(line["id"],line["gender"])
except KeyError:
print(line["id"],"Error!!! no gender!")
This is called ErrorHandling. Read the docs here: https://docs.python.org/3.6/tutorial/errors.html
update: Do you mean this? update2 corrected misstake
try:
gender = definegender(line["gender"])
except KeyError:
gender = definegender(None)
print(line["id"],gender)
update3: (for future purposes)
as .get() returns None by default the most simple solution would be
gender = definegender(line.get("gender"))
print(line["id"],gender)
Upvotes: 1
Reputation: 140266
why not using a default value for your dictionary in dict.get
?
print(line["id"],line.get("gender","unknown"))
And since you want to transform input further, you could nest two dict.get
together, the first one with None
as default value, and a new table, like this:
gender_dict = {"Male":"M", "Female":"F", None : "unknown"}
print(line["id"],gender_dict.get(line.get("gender")))
(note that you don't need your overcomplex gender conversion method anymore)
Upvotes: 6
Reputation: 378
Why not simplify this with an if-statement?
for line in data:
if "gender" in line:
print(line)
Upvotes: 1