Search code examples
pythonpython-3.xlistdictionaryclass-attributes

Delete dictionary from a list in class attribute


I have a list saved as a class attribute and I am trying to delete a specific dictionary in that list.

The project is a simple one, one where the user should be able to add items to a collection (saved in a list), edit them, filter search results by types (previously added to list) and delete dictionary entries from list.

Here is the constructor:

class Item:
    py_collection_list = []

    def __init__(self, item_name: str, item_type: str, date_add, dom, item_info: str):
        self.__id = Item.get_next_id()
        self.item_name: str = item_name
        self.item_type: str = item_type
        self.date_add = date_add
        self.dom = dom
        self.item_info: str = item_info
        Item.py_collection_list.append(self)

(Item being the super class and py_collection_list being the list)

I was able to create a filter with the following code:

def show_items():
    print('View items by type \nComputer | Camera | Phone | Video Player ')
    type_selection = input('Type> ')
    print("{0:3}\t{1:20}\t{2:10}\t{3:10}".format("ID", "Item", "Date added", "Date manufactured"))
    for i in Item.py_collection_list:
        if type_selection == i.item_type:
            print("{0:03d}\t{1:20}\t{2:10}\t{3:10}".format(i.get_id(), i.item_name, i.date_add, i.dom))

I used several options for the deletion and this is the latest one which isn't working:

def delete_item():
    print("{0:3}\t{1:20}\t{2:10}\t{3:10}".format("ID", "Item", "Date added", "Date manufactured"))
    for i in Item.py_collection_list:
        print("{0:03d}\t{1:20}\t{2:10}\t{3:10}".format(i.get_id(), i.item_name, i.date_add, i.dom))
    remove_item = input("Type name of the item you would like to delete from collection> ")
    if remove_item == i.item_name:
        del [remove_item]

Solution

  • In your delete_item method, you only check equality for the last element in your list.

    Your for loop works by going through your list and assigning each value to i. After your list is exhausted and you've exited it, i still contains the last value it was assigned. That is the only element you check for equality with remove_item.

    The easiest way to check for equality for all items and filter the ones that don't match would be a list comprehension.

    def delete_item():
        print("{0:3}\t{1:20}\t{2:10}\t{3:10}".format("ID", 
                                                     "Item", 
                                                     "Date added", 
                                                     "Date manufactured"))
        for i in Item.py_collection_list:
            print("{0:03d}\t{1:20}\t{2:10}\t{3:10}".format(i.get_id(), 
                                                           i.item_name, 
                                                           i.date_add, 
                                                           i.dom))
        remove_item = input("Type name of the item you would like to delete from collection>")
        Item.py_collection_list = [i for i in Item.py_collection_list if i.item_name != remove_item]
    
    

    This allows you to filter multiple entries in one shot and isn't committing an atrocity like mutating your list as you iterate.