Home > Enterprise >  Removing a key from a dictionary using the value
Removing a key from a dictionary using the value

Time:12-01

Can I somehow delete a value from a dictionary using its key? The function del_contact is supposed to delete a contact using only the name of the contact, but unfortunately I have the dictionary and the value, but not the key. How can this be solved?

my_contacts = {
    1: {
        "Name": "Tom Jones",
        "Number": "911",
        "Birthday": "22.10.1995",
        "Address": "212 street"
    },
    2: {
        "Name": "Bob Marley",
        "Number": "0800838383",
        "Birthday": "22.10.1991",
        "Address": "31 street"
    }
}


def add_contact():
    user_input = int(input("please enter how many contacts you wanna add: "))
    index = len(my_contacts)   1
    for _ in range(user_input):
        details = {}
        name = input("Enter the name: ")
        number = input("Enter the number: ")
        birthday = input("Enter the birthday")
        address = input("Enter the address")

        details["Name"] = name
        details["Number"] = number
        details["Birthday"] = birthday
        details["Address"] = address

        my_contacts[index] = details
        index  = 1
    print(my_contacts)


def del_contact():
    user_input = input("Please enter the name of the contact you want to delete: ")
    my_contacts.pop(user_input)


add_contact()
print(my_contacts)

The problem is that my key of the dictionary is 1 or Name, and I want to be able to remove the contact using only the value of Name.

CodePudding user response:

Basically what you can do is iterate of the dict and save only the keys without that user's name.

This code will do the trick:

my_contacts = {1: {"Name": "Tom Jones",
                   "Number": "911",
                   "Birthday": "22.10.1995",
                   "Address": "212 street"},
               2: {"Name": "Bob Marley",
                   "Number": "0800838383",
                   "Birthday": "22.10.1991",
                   "Address": "31 street"}
               }
user_input = "Tom Jones"

my_contacts = {key: value for key, value in my_contacts.items() if value["Name"] != user_input}

CodePudding user response:

There's two steps here:

  1. Finding the key/value pair(s) that match
  2. Deleting the keys you found

If you're only deleting a single item (even with multiple matches), always, these can be combined:

def del_contact():
    user_input = input("Please enter the name of the contact you want to delete: ")
    for k, v in my_contacts.items():  # Need both key and value, we test key, delete by value
        if v["Name"] == user_input:
            del my_contacts[k]
            break  # Deleted one item, stop now (we'd RuntimeError if iteration continued)
    else:
        # Optionally raise exception or print error indicating name wasn't found

If you might delete multiple entries, and must operate in place, you'd split the steps (because it's illegal to continue iterating a dict while mutating the set of keys):

def del_contact():
    user_input = input("Please enter the name of the contact you want to delete: ")
    to_delete = [k for k, v in my_contacts.items() if v["Name"] == user_input]
    if not to_delete:
        # Optionally raise exception or print error indicating name wasn't found
    for k in to_delete:
        del my_contacts[k]

Or if you're okay with replacing the original dict, rather than mutating it in place, you can one-line the multi-deletion case as:

def del_contact():
    global my_contacts  # Assignment requires explicitly declared use of global
    user_input = input("Please enter the name of the contact you want to delete: ")
    my_contacts = {k: v for k, v in my_contacts.items() if v["Name"] != user_input}  # Flip test, build new dict
    # Detecting no matches is more annoying here (it's basically comparing
    # length before and after), so I'm omitting it

CodePudding user response:

I think thats what you need, hope that helps:

Code:

my_contacts = {1: {"Name": "Tom Jones",
                   "Number": "911",
                   "Birthday": "22.10.1995",
                   "Address": "212 street"},
               2: {"Name": "Bob Marley",
                   "Number": "0800838383",
                   "Birthday": "22.10.1991",
                   "Address": "31 street"}
           }

def add_contact():
    user_input = int(input("please enter how many contacts you wanna add: "))
    index = len(my_contacts)   1
    for _ in range(user_input):
        details = {}
        name = input("Enter the name: ")
        number = input("Enter the number: ")
        birthday = input("Enter the birthday")
        address = input("Enter the address")
        details["Name"] = name
        details["Number"] = number
        details["Birthday"] = birthday
        details["Address"] = address
        my_contacts[index] = details
        index  = 1
    print(my_contacts)

add_contact()

print(my_contacts)
def del_contact():
    user_input = input("Please enter the name of the contact you want to delete: ")
    values = [key for key in my_contacts.keys() if user_input in my_contacts[key].values()]
    for value in values:
        my_contacts.pop(value)
del_contact()
print(my_contacts)

Input:

{1: {'Name': 'Tom Jones', 'Number': '911', 'Birthday': '22.10.1995', 'Address': '212 street'}, 2: {'Name': 'Bob Marley', 'Number': '0800838383', 'Birthday': '22.10.1991', 'Address': '31 street'}, 3: {'Name': 'myname', 'Number': '1233455', 'Birthday': '12-12-22', 'Address': 'blabla street'}}
Please enter the name of the contact you want to delete: Bob Marley

Output:

{1: {'Name': 'Tom Jones', 'Number': '911', 'Birthday': '22.10.1995', 'Address': '212 street'}, 3: {'Name': 'myname', 'Number': '1233455', 'Birthday': '12-12-22', 'Address': 'blabla street'}}

CodePudding user response:

Being that the index are used as keys for the dictionary, the range function can be used as follows:

def del_contact():
    user_input = input("Please enter the name of the contact you want to delete: ")
    for i in range(1,len(my_contacts) 1):
        if my_contacts[i]['Name'] == user_input:
            del my_contacts[i]
            break

If there can be multiple contacts with the same name that need to be deleted, remove the break statement.

But as mentioned in the comments, there is no need to use an index as a key for the dictionaries. A potential bug you'll encounter with that, is if the first entry is deleted whose name is Tom Jones the dict will have a length of 1 with only one key - 2. Then when you try to add more contacts, when you check the length of the dictionary index = len(my_contacts) 1, since length is 1, index will be 2. Hence my_contacts[index] = details will update the contact with a key of 2 or "Name": "Bob Marley" instead of adding a new contact.

  • Related