Recent chats
ASKGEEZ Q&A GUIDETechnology & devices

Why does `dict.get()` return `None` when a key is missing?

Quick answer

dict.get(key) returns None when the key is absent; unlike my_dict[key], it does not raise KeyError for that missing key. You can provide a second argument, such as dict.get(key, "unknown"), to return your chosen default instead. But if the result is None, that alone cannot tell you whether the key was absent or present with a stored None; check membership when that distinction matters. [S1]

LET’S WORK THROUGH IT

The question, the details, the next step.

Question

Why does settings.get("theme") give me None when I expected a value? I thought get() was meant to find the key.

Geez

get() looks up a key, but it also gives you a way to handle a key that is not in the dictionary. If the key is absent and you call settings.get("theme") with no second argument, the result is None. That is the default behavior, not evidence that Python found a theme value.

Direct indexing works differently for a missing key: settings["theme"] raises KeyError. Use it when the key is required and you want a missing key to be an error. Use get() when the key may be absent and you want to choose what happens instead. [S1]

For example, if settings is {}:

settings["theme"]          # raises KeyError
settings.get("theme")     # returns None
settings.get("theme", "light")  # returns "light"

The second argument is the value returned when the key is absent. Choose a default that makes sense for what your code will do next.

Follow-up question

So should I always pass a default? What would that look like if I want to display a friendly label?

Geez

Pass a default when you have a meaningful fallback and want the lookup itself to supply it. For a display label, you might use:

label = profile.get("display_name", "Guest")
print(label)

If profile has no "display_name" key, label becomes "Guest". If the key exists, get() returns its stored value instead. [S1]

A default is not a repair for every unexpected value. For instance, if your program requires a name and silently substituting "Guest" would hide a problem, direct indexing—or an explicit check followed by a clear error—may fit better. Decide what a missing key should mean in this particular part of the program before choosing a fallback.

Follow-up question

I used profile.get("display_name") and got None. How can I tell whether the key is missing or its value is actually None?

Geez

You cannot tell from that result alone. Both an absent key looked up without a default and a present key whose value is None can produce the same result. When the distinction matters, test whether the key is in the dictionary:

profile = {"display_name": None}

if "display_name" in profile:
    print("The key exists; its value is", profile["display_name"])
else:
    print("The key is missing")

Here, membership says the key exists even though its stored value is None. By contrast, if profile were {}, the else branch would run. The documentation recommends membership testing for this distinction. [S1]

This is useful when None has its own meaning in your program—for example, when it differs from a field that was never provided. If you do not need to distinguish those cases, a suitable get() default may be simpler.

Follow-up question

Can you give me a compact pattern I can adapt, and a rule for choosing among indexing, get(), and checking membership?

Geez

Use the pattern that matches what absence means to your code:

# Required key: let an absent key raise KeyError.
name = profile["display_name"]

# Optional key with a fallback for absence.
name = profile.get("display_name", "Guest")

# Need to distinguish absent from present-with-None.
if "display_name" in profile:
    name = profile["display_name"]
else:
    name = "Guest"

For a worked example, suppose profile is {"display_name": None}. Direct indexing returns the stored None; get("display_name", "Guest") also returns the stored None, because the key is present. The membership branch confirms the key exists. If the dictionary is {}, indexing raises KeyError, get("display_name", "Guest") returns "Guest", and membership reports that the key is absent. [S1]

Reusable decision: require the value → index directly; allow absence with one fallback → call get(key, fallback); treat absence differently from stored None → test key in dictionary. The documentation establishes these lookup behaviors; it does not determine which default or error handling is right for your application. Choose that based on your program’s needs.

A practical checklist

  • Decide whether the key is required or may be absent.

  • Use direct indexing when a missing key should raise KeyError.

  • Use get(key, fallback) when absence should produce a chosen fallback.

  • Check key in dictionary when absence must differ from a stored None.

  • Try the pattern with both an absent key and a key whose value is None.

A few more useful answers

What happens if I omit the default argument to `get()`?

If the key is absent and you provide no default, get() returns None. If you supply a default, it returns that value when the key is absent. [S1]

If I pass a default to `get()`, will it replace a stored `None`?

No. The specified default is returned when the key is absent. If the key exists with a stored value of None, the lookup returns that stored value. [S1]

When is direct indexing preferable?

Use direct indexing when the key is required and a missing key should raise KeyError. Use get() when absence is expected and you have a suitable fallback. [S1]

Sources

References used for this guide.

  1. [S1] Python 3.15 tutorial: dictionary lookup with get()
    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