Problem overview
The method addContact gets a phone book phoneBook, a dictionary from names to phone numbers, plus a name and a number. It adds the name with its number to the phone book and returns the phone book. A name that is already there keeps its old number, and the order of the entries doesn't matter. The phone book may be empty.
Examples:
- With
{"Ana": "555-0142", "Ben": "555-0199"}, adding"Cara"with"555-0123"gives a book with three contacts. - Adding
"Ben"with"555-0100"changes nothing. Ben keeps"555-0199". - With an empty book, adding
"Max"gives{"Max": "555-0100"}.
Approach: add only when the key is new
Assigning to a key, phoneBook[name] = number, does two different things: it adds the key when it is new, and it replaces the value when the key exists. This task wants only the first. So the assignment must be guarded by a check that the name is not a key yet. name not in phoneBook is that check, and it looks at keys only, which is what you want: phone numbers are values and may be shared by two people.
If the name is already there, the function does nothing and still returns the book. The empty book needs no special case, since no name is in an empty dictionary.
Step by step
- Write an
ifwithname not in phoneBook. Its body comes next, indented. - Inside the
if, storenumberunder the keyname: assigning to a key that isn't there adds it, with its value. - After the
if, returnphoneBook. It now has the new contact, or it is as it was.
The solution in Python
class Solution:
def addContact(self, phoneBook: Dict[str, str], name: str, number: str) -> Dict[str, str]:
if name not in phoneBook:
phoneBook[name] = number
return phoneBook
On the three examples it returns:
{'Ana': '555-0142', 'Ben': '555-0199', 'Cara': '555-0123'}
{'Ana': '555-0142', 'Ben': '555-0199'}
{'Max': '555-0100'}
The method changes the dictionary it was given and returns that same object. A dictionary is not copied when passed to a function, so the caller's variable shows the new contact as well. The return line sits at the same indentation as the if, so it runs in both cases.
Another way: setdefault
The dictionary method setdefault(key, value) does the same check and store in one call: it adds the key with the value only when the key is missing, and leaves an existing key alone.
book = {"Ana": "555-0142", "Ben": "555-0199"}
book.setdefault("Ben", "555-0100")
book.setdefault("Cara", "555-0123")
print(book)
{'Ana': '555-0142', 'Ben': '555-0199', 'Cara': '555-0123'}
The explicit if is easier to read while you are learning, because the rule is written out.
Edge cases and common mistakes
- Assigning without the check.
phoneBook[name] = numberon its own overwrites. For the second example, Ben would end up with555-0100. - Using
ininstead ofnot in. The contact would be stored only when the name is already there, so new names would never be added. - Checking the number.
number not in phoneBookasks about keys, and numbers are values. The check must usename. - Returning inside the
if. The function would returnNonefor a name already in the book.
Testing
Besides the three examples, add a name that differs only in case from an existing one, such as "ben". Keys match exactly, so it is a new contact and is added.
