Skip to main content

How to Validate Keys and Values in Python Dictionaries

Dictionary validation is the process of verifying that a dictionary contains the correct structure, required keys, and valid data types before processing it. This is essential for ensuring robust code when dealing with external data like API responses, user configurations, or JSON files.

This guide explores manual validation methods, schema-based validation, and modern solutions using Pydantic.

Method 1: Manual Validation (Basic)

For simple scripts, you can manually check keys and types using if statements. This involves checking if required keys exist (in) and if their values match expected types (isinstance).

user_data = {
"username": "alice",
"age": 30,
"email": "alice@example.com"
}

required_keys = ["username", "age"]

# 1. Check for missing keys
missing_keys = [key for key in required_keys if key not in user_data]

if missing_keys:
print(f"Error: Missing keys {missing_keys}")
else:
# 2. Check types
if not isinstance(user_data["age"], int):
print("Error: Age must be an integer.")
elif user_data["age"] < 0:
print("Error: Age cannot be negative.")
else:
print("Validation successful.")

Output:

Validation successful.

Method 2: Validation Functions (Modular)

As data complexity grows, writing manual checks becomes tedious. You can create a schema dictionary mapping keys to validator functions.

def validate_email(email):
return isinstance(email, str) and "@" in email

def validate_age(age):
return isinstance(age, int) and 0 < age < 120

# Define schema: key -> validation function
schema = {
"username": lambda x: isinstance(x, str) and len(x) > 3,
"email": validate_email,
"age": validate_age
}

def validate_dict(data, schema):
for key, validator in schema.items():
if key not in data:
return False, f"Missing key: {key}"
if not validator(data[key]):
return False, f"Invalid value for key: {key}"
return True, "Valid"

data = {"username": "bob", "email": "bob@test", "age": 25}
is_valid, message = validate_dict(data, schema)

print(f"Result: {is_valid} - {message}")

Output:

Result: False - Invalid value for key: username
note

'bob@test' failed because while it has an '@', simplistic validation logic is fragile. Real validation usually requires regex.

In modern Python development (especially web APIs and data science), manual validation is often replaced by Pydantic. Pydantic enforces type hints at runtime and provides detailed error messages automatically.

Installation: pip install pydantic

from pydantic import BaseModel, ValidationError, EmailStr, Field

class User(BaseModel):
username: str = Field(min_length=3)
age: int = Field(gt=0, lt=120)
email: str # Standard string, or use EmailStr for stricter validation

try:
# This will validate types and constraints automatically
user = User(username="alice", age=30, email="alice@example.com")
print("User validated:", user)

# Example of invalid data
invalid_user = User(username="al", age="twenty", email="bad-email")
except ValidationError as e:
print("\nValidation Errors:")
print(e.json(indent=2))

Output (Simulated):

User validated: username='alice' age=30 email='alice@example.com'

Validation Errors:
[
{
"type": "string_too_short",
"loc": ["username"],
"msg": "String should have at least 3 characters",
"input": "al",
"ctx": {
"min_length": 3
},
"url": "https://errors.pydantic.dev/2.10/v/string_too_short"
},
{
"type": "int_parsing",
"loc": ["age"],
"msg": "Input should be a valid integer, unable to parse string as an integer",
"input": "twenty",
"url": "https://errors.pydantic.dev/2.10/v/int_parsing"
}
]

Common Pitfall: Missing Keys

A common mistake is checking if key in dict and assuming the value is not None. A key can exist but have a None value.

data = {"id": 1, "config": None}

# ⛔️ Incorrect: Assumes "config" has data because key exists
if "config" in data:
# data["config"]["setting"] would crash
print("Config key present.")

# ✅ Correct: Check for value validity
if data.get("config"):
print("Config has data.")
else:
print("Config is missing or None.")

Output:

Config key present.
Config is missing or None.

Conclusion

To validate dictionaries effectively:

  1. Use Pydantic for robust, production-grade validation with minimal code.
  2. Use Schema Functions for lightweight scripts where external dependencies aren't desired.
  3. Check Types explicitly using isinstance rather than assuming data integrity.