Andres Urrego Angel
Andres Urrego Angel

Reputation: 1932

Python 3 Read a json file with missing objects within lines

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

Answers (3)

Anton vBR
Anton vBR

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

Jean-Fran&#231;ois Fabre
Jean-Fran&#231;ois Fabre

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

giran
giran

Reputation: 378

Why not simplify this with an if-statement?

for line in data:
    if "gender" in line:
        print(line)

Upvotes: 1

Related Questions