Case insensitive Full Name dictionary search

Viewed 56

I am creating a dictionary with "Full Name": "Birthday" for numerous people as an exercise. The program should ask "Who's birthday do you want to look up?" I will input a name, say "Benjamin Franklin" And it will return his birthday: 1706/01/17.

Alright, the problem I am encountering is name capitalization. How can I input "benjamin franklin" and still find "Benjamin Franklin" in my dictionary? I am familiar with .lower() and .upper() functions, however I am not able to implement them correctly, is that the right way to approach this problem?

Here is what I have

bday_dict = {"Person1": "YYYY/MM/DD1",
         "Person2": "YYYY/MM/DD2",
         "Benjamin Franklin": "1706/01/17"}


def get_name(dict_name):

    name = input("Who's birthday do you want to look up? > ")
    return name


def find_bday(name):

    print(bday_dict[name])


find_bday(get_name(bday_dict))
3 Answers

The best way to do this is to keep the keys in your dictionary lowercase. If you can't do that for whatever reason, have a dictionary from lowercase to the real key, and then keep the original dictionary.

Otherwise, Kraigolas's solution works well, but it is O(N) whereas hashmaps are supposed to be constant-time, and thus for really large dictionaries the other answer will not scale.

So, when you are setting your keys, do bday_dict[name.lower()] = value and then you can query by bday_dict[input.lower()].

Alternatively:

bday_dict = {"John": 1}
name_dict = {"john": "John"}

def access(x):
    return bday_dict[name_dict[x.lower()]]

Probably the most straight forward way I can think of to solve this is the following:

def get_birthday(name):
    global bday_dict
    for person, bday in bday_dict.items():
        if name.lower() == person.lower():
            return bday
    return "This person is not in bday_dict"

Here, you just iterate through the entire dictionary using the person's name paired with their birthday, and if we don't find them, just return a message saying we don't have their birthday.

If you know that all names will capitalize the first letter of each word, you can just use:

name = ' '.join([word.capitalize() for word in name.split()])

then you can just search for that. This is not always the case. For example, for "Leonardo da Vinci" this will not work, so the original answer is probably the most reliable way to do this.

One final way to do this would be to just store the names as lowercase from the beginning in your dictionary, but this might not be practical when you want to draw a name from the dictionary as well.

Depending what your exercise allows, I would put the names in the dictionary as all lowercase or uppercase. So:

bday_dict = {"person1": "YYYY/MM/DD1",
     "person2": "YYYY/MM/DD2",
     "benjamin franklin": "1706/01/17"}

And then look up the entered name in the dictionary like this:

def find_bday(name):
    print(bday_dict[name.lower()])

You may also want to do a check that the name is in the dictionary beforehand to avoid an error:

def find_bday(name):
    bday = bday_dict.get(name.lower(), None)
    if bday:
        print(bday)
    else:
        print("No result for {}.".format(name))
Related