Validate dictionary data with sets in Python
Validate a dictionary against required keys and allowed value sets, returning a list of validation errors.
Python code
41 linesdef validate_data(data, required_keys, allowed_values=None):
"""
Validate a dictionary against required keys and optional allowed value sets.
Returns a list of validation errors (empty list if valid).
"""
errors = []
# Check for missing required keys
missing = set(required_keys) - set(data.keys())
if missing:
errors.append(f"Missing keys: {sorted(missing)}")
# Check for unexpected keys
unexpected = set(data.keys()) - set(required_keys)
if unexpected:
errors.append(f"Unexpected keys: {sorted(unexpected)}")
# Check allowed values if provided
if allowed_values:
for key, valid_set in allowed_values.items():
if key in data and data[key] not in valid_set:
errors.append(
f"Invalid value for '{key}': {data[key]!r}. "
f"Allowed: {sorted(valid_set)}"
)
return errors
if __name__ == "__main__":
# Example usage for validation
person = {"name": "Alice", "age": 30, "status": "active"}
required = {"name", "age", "status"}
allowed = {"status": {"active", "inactive"}}
errors = validate_data(person, required, allowed)
print("Errors:", errors if errors else "None — data is valid")
# Test with invalid data
bad_person = {"name": "Bob", "status": "unknown"}
errors = validate_data(bad_person, required, allowed)
print("Errors:", errors if errors else "None — data is valid")
Output
Errors: None — data is valid
Errors: ['Missing keys: [\'age\', \'status\']', "Invalid value for 'status': 'unknown'. Allowed: ['active', 'inactive']"]
How it works
set(required_keys) - set(data.keys()) finds missing keys as a set difference, and set(data.keys()) - set(required_keys) finds unexpected extra keys. The allowed_values mapping lets you restrict specific keys to a set of permitted values using set membership. The function builds a list of human-readable error strings, returning an empty list when the data passes all checks. Using sets for key comparison handles duplicates and is more readable than manual loops.
Common mistakes
- Using lists instead of sets leads to slower membership tests and less readable difference operations.
- Forgetting that `allowed_values` keys must be a subset of `required_keys` for the validation to catch invalid values.
- Returning `True`/`False` instead of an errors list makes it harder to show specific problems.
Variations
- Use `json.loads` to validate data coming from an API payload before applying it.
- Return a boolean plus a message instead of an errors list by wrapping this function.
Real-world use cases
- Validating user registration data before creating a database record.
- Checking configuration files against expected keys and allowed enum-like values.
- Sanitizing incoming webhook payloads to prevent unexpected fields from being processed.
Sponsored
More from Dictionaries & sets
- Build a Case-Insensitive Dict with a Wrapper Class in Python medium
- Build a defaultdict histogram of categories in Python easy
- Build adjacency dict graph from edges in Python easy
- Build an OrderedDict insertion order demo in Python 3 easy
- Check Invertible Mapping for Duplicate Values in Python easy
- Compare Two Dictionaries in Python easy
Keep learning
Related tutorials and quizzes for this topic.