Python has no built-in syntax like d["a", "b"] for reading several keys at once (that would look up the tuple key ("a", "b")). Use a list comprehension to get the values, [d[k] for k in keys], or a dictionary comprehension to get a smaller dictionary, {k: d[k] for k in keys}. This guide covers those, operator.itemgetter, missing keys, checking that keys exist, keeping order, nested dictionaries and lists of records, with real output and timings.
Every example is self-contained and was run with Python 3.12.5. For the full reference, see operator.itemgetter() in the Python documentation.
Quick answer: get or select multiple keys
user = {"name": "Emma", "age": 31, "city": "London", "email": "emma@example.com", "plan": "pro"}
keys = ["name", "email", "plan"]
values = [user[k] for k in keys] # just the values
subset = {k: user[k] for k in keys} # a smaller dictionary
print(values)
print(subset)
Output:
['Emma', 'emma@example.com', 'pro']
{'name': 'Emma', 'email': 'emma@example.com', 'plan': 'pro'}

operator.itemgetter(): the shortest way
itemgetter(*keys) builds a function that returns the values as a tuple, which is handy for unpacking into variables. Watch the single-key case:
from operator import itemgetter
user = {"name": "Emma", "age": 31, "city": "London", "email": "emma@example.com"}
get_contact = itemgetter("name", "email")
print(get_contact(user)) # a tuple of the values
name, email = itemgetter("name", "email")(user) # unpack straight into variables
print(name, "|", email)
print(itemgetter("name")(user)) # careful: ONE key returns the value, not a 1-tuple
Output:
('Emma', 'emma@example.com')
Emma | emma@example.com
Emma
With exactly one key, itemgetter returns the value itself, not a 1-item tuple, which can break code that expects a tuple. If the number of keys varies, use the list comprehension instead.
When some keys are missing
d[k] raises KeyError for a missing key. Use .get() to substitute a default, or filter with if k in d to skip missing keys:
user = {"name": "Emma", "age": 31, "city": "London"}
keys = ["name", "email", "city"]
try:
print([user[k] for k in keys])
except KeyError as err:
print("KeyError:", err)
print([user.get(k) for k in keys]) # None for missing keys
print([user.get(k, "n/a") for k in keys]) # or your own default
print({k: user[k] for k in keys if k in user}) # skip missing keys
Output:
KeyError: 'email'
['Emma', None, 'London']
['Emma', 'n/a', 'London']
{'name': 'Emma', 'city': 'London'}

KeyError; get() avoids it.More on this error in Python dictionary KeyError.
Check whether several keys exist
d.keys() behaves like a set, so set operators answer “all present?”, “any present?” and “which are missing?” in one expression:
user = {"name": "Emma", "age": 31, "city": "London"}
required = {"name", "email", "city"}
print(required <= user.keys()) # are ALL keys present? (dict keys act like a set)
print(bool(required & user.keys())) # is ANY of them present?
print(required - user.keys()) # which ones are missing?
Output:
False
True
{'email'}
For a single key, see check if a key exists in a dictionary.
Keep the order of the keys
Set intersection is short, but the result is a set: its order isn’t guaranteed. Use a comprehension when order matters, looping over your key list or over the dictionary, depending on which order you want:
user = {"name": "Emma", "age": 31, "city": "London", "email": "emma@example.com"}
wanted = ["email", "name", "zip"]
print(user.keys() & wanted) # a set: order not guaranteed, missing keys dropped
print({k: user[k] for k in wanted if k in user}) # keeps YOUR order
print({k: v for k, v in user.items() if k in set(wanted)}) # keeps the DICTIONARY'S order
Output:
{'name', 'email'}
{'email': 'emma@example.com', 'name': 'Emma'}
{'name': 'Emma', 'email': 'emma@example.com'}
Select keys by a condition
config = {"db_host": "localhost", "db_port": 5432, "db_user": "app",
"cache_ttl": 300, "debug": True}
db_settings = {k: v for k, v in config.items() if k.startswith("db_")}
numbers = {k: v for k, v in config.items() if isinstance(v, int) and not isinstance(v, bool)}
print(db_settings)
print(numbers)
Output:
{'db_host': 'localhost', 'db_port': 5432, 'db_user': 'app'}
{'db_port': 5432, 'cache_ttl': 300}
bool is a subclass of int in Python, which is why the second filter excludes it explicitly.
Get multiple values from a nested dictionary
A small helper that follows dotted paths returns a default instead of crashing when a level is missing:
order = {
"id": 1042,
"customer": {"name": "Liam", "address": {"city": "Leeds", "zip": "LS1"}},
"total": 59.90,
}
def get_path(data, path, default=None):
"""Follow a dotted path such as 'customer.address.city'."""
for part in path.split("."):
if not isinstance(data, dict) or part not in data:
return default
data = data[part]
return data
paths = ["id", "customer.name", "customer.address.city", "customer.phone"]
print({p: get_path(order, p) for p in paths})
Output:
{'id': 1042, 'customer.name': 'Liam', 'customer.address.city': 'Leeds', 'customer.phone': None}
Select the same keys from a list of dictionaries
Common with JSON data and database rows, for example to drop private fields before returning data from an API:
rows = [
{"id": 1, "name": "Emma", "email": "emma@example.com", "password_hash": "x1"},
{"id": 2, "name": "Liam", "email": "liam@example.com", "password_hash": "x2"},
]
public = ("id", "name", "email")
safe_rows = [{k: row[k] for k in public} for row in rows] # e.g. before sending as JSON
for row in safe_rows:
print(row)
Output:
{'id': 1, 'name': 'Emma', 'email': 'emma@example.com'}
{'id': 2, 'name': 'Liam', 'email': 'liam@example.com'}
Which method is fastest?
For 50 keys out of 1,000, measured with timeit (best of 5 runs):
import timeit
from operator import itemgetter
d = {f"key{i}": i for i in range(1_000)}
keys = [f"key{i}" for i in range(0, 1_000, 20)] # 50 keys to select
getter = itemgetter(*keys)
tests = {
"list comprehension": lambda: [d[k] for k in keys],
"itemgetter": lambda: getter(d),
"map(d.get, keys)": lambda: list(map(d.get, keys)),
"dict comprehension": lambda: {k: d[k] for k in keys},
}
for name, fn in tests.items():
t = min(timeit.repeat(fn, number=20_000, repeat=5)) / 20_000
print(f"{name:20} {t * 1e6:6.2f} microseconds")
Output:
list comprehension 1.27 microseconds
itemgetter 0.62 microseconds
map(d.get, keys) 1.25 microseconds
dict comprehension 2.71 microseconds

All four are fast; itemgetter is quickest because the loop runs in C. Choose the one that reads best unless it runs millions of times.
A dictionary with multiple keys (tuple keys)
If you meant one entry identified by several values, such as a pair of cities, use a tuple as the key. Tuples are hashable, lists aren’t:
# a dictionary with multiple keys per entry: use a tuple as the key
distances = {
("London", "Paris"): 344,
("London", "Berlin"): 932,
("Paris", "Berlin"): 878,
}
print(distances[("London", "Paris")])
print(distances.get(("Paris", "Rome"), "unknown"))
# all entries that start in London
print({k: v for k, v in distances.items() if k[0] == "London"})
Output:
344
unknown
{('London', 'Paris'): 344, ('London', 'Berlin'): 932}

Many keys with the same value
# many keys that share one value
status = dict.fromkeys(["emma", "liam", "ava"], "active")
print(status)
# careful with mutable defaults: every key gets the SAME list
groups = dict.fromkeys(["a", "b"], [])
groups["a"].append(1)
print(groups)
groups = {k: [] for k in ["a", "b"]} # a new list per key
groups["a"].append(1)
print(groups)
Output:
{'emma': 'active', 'liam': 'active', 'ava': 'active'}
{'a': [1], 'b': [1]}
{'a': [1], 'b': []}
dict.fromkeys() shares one object between all keys, so only use it with immutable defaults. For several values under one key, see Python dictionary with multiple values.
Update or remove several keys at once
user = {"name": "Emma", "plan": "free", "active": False}
user.update({"plan": "pro", "active": True}) # change several keys at once
print(user)
user |= {"city": "London"} # Python 3.9+: merge in place
print(user)
Output:
{'name': 'Emma', 'plan': 'pro', 'active': True}
{'name': 'Emma', 'plan': 'pro', 'active': True, 'city': 'London'}
To delete several keys, see remove multiple keys from a dictionary; to copy a dictionary without some keys, copy a dictionary without some of its keys.
Summary
| Goal | Code |
|---|---|
| Values of several keys | [d[k] for k in keys] |
| A smaller dictionary | {k: d[k] for k in keys} |
| Unpack into variables | a, b = itemgetter("a", "b")(d) |
| Missing keys allowed | [d.get(k) for k in keys] or if k in d |
| All keys present? | set(keys) <= d.keys() |
| Which keys are missing? | set(keys) - d.keys() |
| Keys by condition | {k: v for k, v in d.items() if ...} |
| Composite key | d[(a, b)] with tuple keys |
Frequently asked questions
How do I get multiple keys from a dictionary in Python?
Use a list comprehension, [d[k] for k in keys], for the values or a dictionary comprehension, {k: d[k] for k in keys}, for a sub-dictionary. operator.itemgetter(*keys)(d) returns the values as a tuple.
How do I select multiple keys without a KeyError?
Use d.get(k) (returns None or a default) or skip missing keys: {k: d[k] for k in keys if k in d}.
How do I check if multiple keys are in a dictionary?
set(keys) <= d.keys() is True when all are present; set(keys) - d.keys() lists the missing ones.
Can a Python dictionary have multiple keys for one value?
Each key maps to one value, but several keys can hold the same value, e.g. dict.fromkeys(["a", "b"], 0). To identify one entry by several values, use a tuple key such as d[("London", "Paris")].
Why does d[‘a’, ‘b’] not return two values?
Python reads d["a", "b"] as a lookup of the single tuple key ("a", "b"). Use a comprehension or itemgetter instead.
You may also like these dictionary tutorials:

Bijay Kumar is a 13-time Microsoft MVP with more than 18 years in software development, and the founder of Python Guides and TSinfo Technologies. He started out building .NET and SharePoint solutions at HP, TCS and KPIT before moving into Python, machine learning and AI, and he also builds web apps with TypeScript and React. He writes the tutorials here himself, and every example is run before publishing so you see the real output. More about Bijay · Microsoft MVP profile · LinkedIn