Recent chats
ASKGEEZ Q&A GUIDETechnology & devices

How can I distinguish a missing JSON key from a key set to null?

Quick answer

After Python decodes JSON, an object becomes a dictionary and JSON null becomes Python None. Check "field" in record first. If the key is present, record["field"] is None tells you its value is null. If it is absent, membership is false. Avoid using record.get("field") is None alone: get() also returns None by default when the key is missing. [S1] [S2]

LET’S WORK THROUGH IT

The question, the details, the next step.

Question

I loaded JSON into Python, and I need to know whether status was omitted or explicitly set to null. Aren't both just None?

Geez

The values can look the same if you only retrieve them, but the dictionary still records whether the key exists. Python's JSON decoder maps a JSON object to a dictionary and JSON null to None. So {"status": null} becomes a dictionary containing status with value None; {} has no status entry. [S1]

Check membership before reading the value:

if "status" not in record:
    print("missing")
elif record["status"] is None:
    print("present, but null")
else:
    print("present with a non-null value")

The first branch handles absence. Only after membership succeeds do you inspect the value. This separates the two cases without treating a missing key as a null value.

Follow-up question

Can you show what that produces for both JSON inputs, including a normal value?

Geez

Assuming these are the JSON texts you pass to json.loads, this example shows the distinct outcomes:

import json

examples = [
    '{}',
    '{"status": null}',
    '{"status": "ready"}',
]

for text in examples:
    record = json.loads(text)

    if "status" not in record:
        result = "missing"
    elif record["status"] is None:
        result = "present, but null"
    else:
        result = "present with a non-null value"

    print(result)

The results, in order, are missing, present, but null, and present with a non-null value. The decision comes from the membership and value checks.

Follow-up question

Why not write record.get("status") is None? That looks shorter.

Geez

Because dict.get() returns None by default when the key is missing, and it also returns the stored value when the key exists. A stored JSON null becomes None, so both cases satisfy record.get("status") is None. [S1] [S2]

For example, with record = {}, record.get("status") is None. With record = {"status": None}, it is also None. Membership distinguishes them:

"status" in {}
# False

"status" in {"status": None}
# True

You can use get() with a unique sentinel as its default, but for this task, membership followed by inspection is a clear check.

Follow-up question

What's the simplest pattern to reuse when I need to handle missing, null, and ordinary values differently?

Geez

Use this three-way pattern, replacing field and the handling code with your own key and actions:

if "field" not in record:
    # Handle an omitted key.
    ...
elif record["field"] is None:
    # Handle a present JSON null.
    ...
else:
    value = record["field"]
    # Handle a present, non-null value.
    ...

Keep the order: test membership first, then use subscription only in branches where the key is known to exist. This check distinguishes key presence and nullness; it does not validate that the value has the type your application expects.

A practical checklist

  • Decode the JSON into a Python dictionary.

  • Check "field" in record to test whether the key exists.

  • If the key exists, check record["field"] is None for JSON null.

  • Handle the remaining present, non-null value according to your needs.

  • Do not use record.get("field") is None alone when missing and null must differ.

A few more useful answers

What happens if I use `record["field"]` when the key is missing?

Dictionary subscription with a missing key raises KeyError. Check membership first if you need to handle absence without that exception. [S2]

Can I use a custom default with `get()` instead?

Yes. A unique sentinel can distinguish a missing key from a stored None, but membership followed by inspection is often easier to read when you need separate branches.

Does this check validate the whole JSON object?

No. It distinguishes key absence from a present null value; it does not validate a schema or establish that other keys or values are acceptable.

Sources

References used for this guide.

  1. [S1] json — JSON encoder and decoder — Python 3.15.2 documentation
    docs.python.org · Checked
  2. [S2] Python Tutorial: Data Structures — Dictionaries
    docs.python.org · Checked

YOUR QUESTION. YOUR DETAILS.

Let’s work through your situation.

Get a tailored answer or help with your next task. Starts at $1, with a quote before you pay.

Ask your own question
← Back to Geez at Work