Why check first
Reading a key that isn't in a dictionary is an error. With capitals = {"France": "Paris", "Japan": "Tokyo"}, the expression capitals["Spain"] stops the program with KeyError: 'Spain'. So when a key might be missing, ask first.
in and not in
key in d is True when key is one of the dictionary's keys and False when it isn't. key not in d asks the opposite. The answer is a bool, so it goes straight into an if.
capitals = {"France": "Paris", "Japan": "Tokyo"}
if "Japan" in capitals:
print(capitals["Japan"])
if "Spain" not in capitals:
print("No Spain")
Tokyo
No Spain
The check is quick, even for a large dictionary: Python looks the key up directly instead of scanning every entry.
A value is not a key
The operator in looks only at the keys. The value "Paris" is not a key, so "Paris" in capitals is False. To look among the values, ask the values: "Paris" in capitals.values() is True. A key must also match exactly, upper and lower case included, so "japan" in capitals is False.
print("Paris" in capitals)
print("Paris" in capitals.values())
print("japan" in capitals)
False
True
False
The lesson's task
In pets, each key is a pet's name and each value is its kind: {"Rex": "dog", "Tom": "cat", "Polly": "parrot"}. The task has two checks.
First, check whether "Tom" is a key. It is, so the code prints Tom is a followed by Tom's kind, read with pets["Tom"]. The read is safe because the if already proved the key exists. Second, check that "cat" is not a key, with not in. The word "cat" appears in pets only as a value, Tom's kind, so it is not a key and the second line prints.
pets = {"Rex": "dog", "Tom": "cat", "Polly": "parrot"}
if "Tom" in pets:
print("Tom is a " + pets["Tom"])
if "cat" not in pets:
print("cat is not a key")
Tom is a cat
cat is not a key
Two meanings of the word in
The word in is also part of the for loop: for name in pets: walks through the keys, one per pass. That is a loop, not a question, and it does not give True or False. In an if condition, in is the question. Both use the keys of the dictionary, which is why checking a key and looping over keys feel alike.
Check, then choose
The usual shape is an if with an else: do one thing when the key exists and another when it doesn't. The check is about the key's presence, and the two branches say what to do about each case:
ages = {"Ana": 31}
name = "Ben"
if name in ages:
print(ages[name])
else:
print(name, "is not listed")
Ben is not listed
Keys are not only text. Any key type works with in, and the type matters: with d = {1: "one"}, the check 1 in d is True but "1" in d is False, because the number 1 and the text "1" are different keys. The same is true for tuples used as keys, such as grid positions.
Common mistakes
- Mixing up keys and values.
"cat" in petsisFalsewhile"cat" in pets.values()isTrue. The task is about keys, so the plain form is the right one. - Reading before checking.
pets["Max"]raises aKeyError. Put the read inside theif, or useget, which the next lesson covers. - Forgetting the space in the text. The output is
Tom is a cat, so the string being joined ends with a space:"Tom is a ". Without it you getTom is acat. - Adding
.keys()for no reason."Tom" in pets.keys()works and givesTrue, but"Tom" in petssays the same thing more simply.
Key takeaways
key in dandkey not in dtest the keys of a dictionary and give abool.- Values are not keys; use
d.values()to search them. - Keys match exactly, including case.
- Check before reading when a key may be missing.
