Python
Dictionary
Type Checking
Programming Tips
Code Snippets

How to check if a variable is a dictionary in Python?

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

Checking whether a value is a dictionary in Python is simple once you decide what “dictionary” means in your code. Sometimes you need the exact built-in dict type, but often what you really need is any object that behaves like a mapping.

Decide Between Exact Type and Mapping Behavior

These are different questions:

  • is the value exactly a dict
  • does the value implement mapping behavior
  • does the value support mutation as well as lookup

Those distinctions matter because Python has several mapping types, including defaultdict, OrderedDict, and custom classes that implement the mapping protocol.

python
1from collections import defaultdict
2from collections.abc import Mapping
3
4plain = {"name": "Ada"}
5custom = defaultdict(int)
6
7print(type(plain) is dict)
8print(type(custom) is dict)
9print(isinstance(plain, Mapping))
10print(isinstance(custom, Mapping))

If the second pair of checks matches your intent better than the first pair, then Mapping is the right abstraction.

Use isinstance in Most Application Code

For inputs such as JSON payloads, configuration objects, or decoded request bodies, isinstance(value, Mapping) is usually the best test.

python
1from collections.abc import Mapping
2
3def ensure_mapping(value):
4    if not isinstance(value, Mapping):
5        raise TypeError("expected a mapping")
6    return value
7
8payload = {"id": 10, "active": True}
9validated = ensure_mapping(payload)
10print(validated["id"])

This accepts ordinary dictionaries and mapping-like objects without forcing every caller to use one exact implementation.

If the code also needs mutation, tighten the check to MutableMapping instead of assuming every mapping can be written to.

Use Exact dict Checks Only When You Mean It

Sometimes exact identity really is the requirement. Maybe you are optimizing for a specific low-level behavior or deliberately rejecting subclasses.

python
1def ensure_plain_dict(value):
2    if type(value) is not dict:
3        raise TypeError("expected plain dict")
4    return value
5
6print(ensure_plain_dict({"x": 1}))

That check is intentionally narrow. It will reject valid mapping types that happen not to be built-in dict objects.

Validate Nested Structures Carefully

Real validation logic usually involves nested dictionaries, not one isolated type check. It is better to validate step by step than to hide everything inside a long boolean expression.

python
1from collections.abc import Mapping
2
3def validate_user(payload):
4    if not isinstance(payload, Mapping):
5        raise TypeError("payload must be a mapping")
6
7    profile = payload.get("profile")
8    if not isinstance(profile, Mapping):
9        raise TypeError("profile must be a mapping")
10
11    email = profile.get("email")
12    if not isinstance(email, str) or not email:
13        raise ValueError("email must be a non-empty string")
14
15    return {
16        "email": email,
17        "newsletter": bool(profile.get("newsletter", False)),
18    }
19
20sample = {
21    "profile": {
22        "email": "[email protected]",
23        "newsletter": 1,
24    }
25}
26
27print(validate_user(sample))

This keeps error messages useful and makes the code easier to maintain.

Type Hints Help, but They Do Not Validate Input

Type hints improve readability and static analysis, but they do not stop invalid runtime input.

python
1from typing import Mapping, Any
2
3def normalize_config(cfg: Mapping[str, Any]) -> dict:
4    timeout = cfg.get("timeout", 30)
5    return {"timeout": int(timeout)}

The hint tells readers what you want. It does not protect you if a caller passes a list or None. If the data crosses a network, file, or user boundary, keep runtime validation in place.

Common Pitfalls

The most common mistake is using type(value) == dict by default and accidentally rejecting perfectly valid mapping types.

Another common issue is trying to detect dictionary-like objects with ad hoc checks such as looking for a keys attribute. Python already has mapping abstractions for this purpose. Developers also sometimes assume type hints enforce runtime behavior automatically, which they do not.

Summary

  • Decide whether you need exact dict identity or general mapping behavior.
  • Prefer isinstance(value, Mapping) for most application-level checks.
  • Use type(value) is dict only when rejecting subclasses is intentional.
  • Use MutableMapping if your code requires writes as well as reads.
  • Keep runtime validation even when type hints are present.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.