1

So I have a method that takes a dictionary object as a parameter. I want to check over the dictionary to make sure it has all the correct keys and if not throw a custom exception. The code I have so far works but I am thinking there might be a better way. (Using Python 2.7)

def my_method(temp_dict):
    #this is the part that looks messy and I would like to improve
    if "key" not in temp_dict:
        raise CustomException("Message key is missing from dict")
    if "key1" not in temp_dict:
        raise CustomException("Message key1 is missing from dict")
    if "key2" not in temp_dict:
        raise CustomException("Message key2 is missing from dict")
    if "key3" not in temp_dict:
        raise CustomException("Message key3 is missing from dict")

my_dict = {}
my_dict["key"] = "test"
my_dict["key1"] = "test"
my_dict["key2"] = "test"

my_method(my_dict)

Link to Python Fiddle Link

5 Answers 5

5

Looping can help:

def my_method(temp_dict):
    for key in ['key1', 'key2', 'key3']
        if key not in temp_dict:
            raise CustomException("Message {} is missing from dict".format(key))
Sign up to request clarification or add additional context in comments.

Comments

2

How about writing all the keys you want to check for in a tuple?

def mymethod(temp_dict):
    mykeys = ('key1', 'key2', 'key3', ..., 'keyN')
    for k in mykeys:
        if k not in temp_dict:
            raise CustomException("{} missing from dictionary".format(k))

In this way anytime you want to add a new key to check for you can just add it to the tuple instead of duplicating code.

Comments

1

One possibility would be to use a schema library such as voluptuous, in which you define your dictionary schema, by defining which keys are required and which are optional and even which acceptable types the keys can have.

On the other hand I have this nifty little function that I've used so far if you would only need to validate if all required keys are present. First we define a list containing all the required keys. Then we check if the given dictionary has all these required keys present using the all method.

def validate_params(params, req_keys=[]):                                           
    """                                                                      
    Verify if all required keys are present in the dictionary passed   
    to this method                                                           

    :param params: Parameter Dictionary to check
    :param req_keys: These Keys are required in the dictionary
    :rtype: Boolean                                                          
    :returns: True or False                                                  
    """                                                                      
    if all(_ in params for _ in req_keys):                       
        return True                                                          
    raise CustomException("Not all keys present in dictionary")                                                             

I've added a fiddle on pythonfiddle.com.

Comments

1

The most Pythonic way to do this is with a loop:

>>> class CustomException(Exception):
...     pass
...
>>> keys = 'key0 key1 key2 key3'.split()
>>> my_dict = {k: v for k, v in zip(keys, xrange(4))}
>>>
>>> for k in keys:
...     if not k in my_dict:
...         raise CustomException('Key %s not in dictionary.' % k)
...
Traceback (most recent call last):
  File "<stdin>", line 3, in <module>
__main__.CustomException: Key key4 not in dictionary.
>>>

However, an even more Pythonic way to do this would be for your function to simply do a try/except for each required key in your function as you use it. For example:

>>> keys = 'key0 key1 key2 key3 key4'.split()
>>>
>>> def f(my_dict):
...     for key in keys:
...         try:
...             print k, my_dict[k]
...         except KeyError:
...             raise CustomException('Key %s not in dictionary.' % k)
...
>>> my_dict = {k: v for k, v in zip(keys[:-1], xrange(len(keys) - 1))}
>>> assert my_dict == {'key0': 0, 'key1': 1, 'key2': 2, 'key3': 3}  # Note no 'key4'
>>> f(my_dict)
key4
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 6, in f
__main__.CustomException: Key key4 not in dictionary.
>>>

This is known as the "Easier to Ask Forgiveness than Permission" (or: "EAFP") principle. Proceed with what you plan to do until something stops you.

Comments

0

Use any function:

if any(k not in temp_dict for k in ('key', 'key1', 'key2', 'key3')):
    raise CustomException("Some keys are missing from dict")

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.