Python
Programming
Dictionary
Coding Practices
Python Functions

Should I use 'has_key()' or 'in' on Python dicts?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

For modern Python code, use in to test whether a key exists in a dictionary. has_key() was a Python 2 method and was removed in Python 3, so it is not a real choice in current codebases. The more useful question is when to use in, when to use get, and when to handle missing keys with exceptions instead.

Why in Is the Right Default

Dictionary membership checks are designed around the in operator.

python
1settings = {"debug": True, "port": 8080}
2
3print("debug" in settings)
4print("host" in settings)

This reads naturally and works in both Python 2 and Python 3. It checks keys, not values. That is important because beginners sometimes expect in on a dictionary to search the values as well.

In practice, key in my_dict is the idiomatic and readable answer whenever you only care about key existence.

has_key() Is Legacy Python 2 Code

Older Python 2 code sometimes looks like this:

python
# Python 2 only
config = {"mode": "prod"}
print(config.has_key("mode"))

That method does not exist in Python 3. If you are maintaining legacy code, replacing has_key() with in is one of the simplest compatibility upgrades you can make.

The removal was not arbitrary. Python already had a generic membership operator, and using one consistent mechanism across containers makes the language easier to read.

Use get When You Need the Value Too

A membership test is not always the best tool. If the next line is going to fetch the value anyway, get may be cleaner.

python
settings = {"debug": True, "port": 8080}
port = settings.get("port", 8000)
print(port)

This is especially useful when a sensible default exists. Instead of checking membership first and then indexing, you can fetch the value and fall back in one step.

Be careful though: get answers a different question. It is about value retrieval with a default, not about distinguishing between a missing key and a present key whose value is None.

Use Direct Indexing When Missing Keys Are Errors

Sometimes a missing key should fail loudly because it indicates broken input or a programming mistake.

python
payload = {"user_id": 42}
user_id = payload["user_id"]
print(user_id)

If user_id is required, this is better than silently using a default. In well-defined code paths, a KeyError can be the right behavior because it exposes the bug immediately.

This is why the decision is not just in versus has_key(). It is about picking the dictionary access pattern that matches your contract.

Avoid Double Lookups When You Do Not Need Them

A pattern like this is common:

python
1if "port" in settings:
2    port = settings["port"]
3else:
4    port = 8000

It is readable, but if your only goal is a default value, get is shorter and avoids an extra lookup.

python
port = settings.get("port", 8000)

The point is not micro-optimization. The point is aligning the code with intent. Use in for membership, get for optional retrieval, and direct indexing for required keys.

Values Need a Different Check

If you need to know whether a value is present anywhere in the dictionary, in on the dictionary itself is the wrong test.

python
settings = {"debug": True, "port": 8080}
print(8080 in settings.values())

That is a separate operation, and it is slower than key lookup because dictionaries are optimized for key access. Make sure the code asks the right question.

Common Pitfalls

  • Using has_key() in code that runs on Python 3.
  • Forgetting that key in my_dict checks keys, not values.
  • Writing a membership test and then an immediate lookup when get would express the intent better.
  • Using get when a missing key should actually raise an error.
  • Treating legacy Python 2 patterns as if they were still current best practice.

Summary

  • In modern Python, use in to check whether a dictionary key exists.
  • 'has_key() is legacy Python 2 code and should not appear in new code.'
  • Use get when you want an optional value with a default.
  • Use direct indexing when the key is required and missing data should fail fast.
  • Choose the access pattern that matches the contract, not just the shortest syntax.

Course illustration
Course illustration

All Rights Reserved.