Checking dict keys to ensure a required key always exists, and that the dict has no other key names beyond a defined set of names

As far as I'm concerned you want to check, that

  1. The set {'field'} is always contained in the set of your dict keys
  2. The set of your dict keys is always contained in the set {'field', 'group', 'function'} So just code it!
required_fields = {'field'}
allowed_fields = required_fields | {'group', 'function'}

d = {'field': 123}  # Set any value here

if required_fields <= d.keys() <= allowed_fields:
    print("Yes!")
else:
    print("No!")

This solution is scalable for any sets of required and allowed fields unless you have some special conditions (for example, mutually exclusive keys)

(thanks to @Duncan for a very elegant code reduction)


Yes, by converting your dict with a dataclass:

from typing import List, Optional
from dataclasses import dataclass

@dataclass
class MyDataclass:
     field: List[str]
     group: Optional[str] = None
     function: Optional[str] = None

result = MyDataclass(["$.name"], "name", "some_function")
# or, equivalently:
result = MyDataclass(field=["$.name"], group="name", function="some_function")

# access with result.field, result.group, result.function

To answer your question directly, you can write the following, and it will throw an exception when a field is missing from the input dictionary:

dict_name = {'field': ['$.name'], 'group': 'name', 'function': 'some_function'}

MyDataclass(*dict_name)

Note that the above only works when your keys are strings, due to the use of the splat operator. (*)

Once converted to a dataclass, you can safely use it assured that it has the fields. This is less prone to errors, because it prevents you from mixing up a dict checked for missing parameters and an unchecked dict in different parts of your code. See Parse, Don't Validate for a full explanation from a theoretical standpoint.

Dataclasses are the idiomatic way to do it in Python, similar to how objects (dictionaries) are the idiomatic way to do it in JavaScript. In addition, if you're using an IDE with mypy/pyre/PEP 484 support, you will get type hints on objects. Thanks to the bidirectionality of PEP 484, that means if you create a dict with a missing field, and pass it to a function that converts it to a dataclass, the type checker may be able to check the error.

You can convert a dataclass back to a dict using dataclasses.asdict.

Another option is namedtuple.


You can also use validation packages like schema https://pypi.org/project/schema/

from schema import Schema, And

my_schema = Schema({
    'field': And(str, len),
    'group': And(str, len),
    'function': And(str, len)
})

data = {
    'field': 'Hello',
    'group': 'This is a group',
    'function': 'some_function'
}

my_schema.validate(data)