Skip to content
Advertisement

Passing dictionary values to a function, with missing keys

I have a class with a constructor that receives several arguments. These arguments I get from an external file, which is a list of dictionaries.

My problem is that some dictionaries have missing fields. If a field is missing, I want the constructor to simply receive None instead. But as the code is written now, it exits on an exception.

This is a simple illustration of the situation

class Person()
    
    def __init__(self, id, age, name, gender):
        self.id = id
        self.age = age
        self.name = name
        self.gender = gender
        

people_list = pickle.load(open("some_file.p", "rb"))
first_person = people_list[0]  # this is a dictionary {'id': '1234', 'age': 27, 'name': 'robert'}
Person(first_person['id'], first_person['age'], first_person['name'], first_person['gender'])

As the code is written right now, I get an exception that 'gender' does not exist as a key in the dictionary, which is true. I want any missing field to gets passed a None value, but without doing a billion ifs or try .. excepts. Is there a good way to do this? Obviously without still incurring an exception.

Advertisement

Answer

In general, you can get a value from a dict with a default if it doesn’t exist with:

d = {'a': 1}
print(d.get('b'))  # prints None

But in your case, this would be more appropriate:

class Person():
    # the defaults are defined in the constructor
    def __init__(self, id, age=None, name=None, gender=None):
        self.id = id
        self.age = age
        self.name = name
        self.gender = gender
        

people_list = pickle.load(open("some_file.p", "rb"))
for person in people_list:
    Person(**person)  # assuming they at least all have an 'id'

Of course, this only works if the keys of the dictionaries match the names of the parameters exactly.

The ** operator ‘unpacks’ the dictionary, so this:

d = {'a': 1, 'b': 2}
f(**d)

Is the same as:

f(a=1, b=2)
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement