0

I am trying to remove the particular value from the list of key. I got Type error. I wrote function to add and remove the key. need to remove a particular value from the key

class my_dict(dict):    
    def add(self, key, value):
        self.setdefault(key, []).append(value)

    def remove_key(self, key):
        del self[key]

    #Error part
    def remove_value(self,key,value):
        for value in dict.values():
            if v in value:
                value.remove(v)

dict_obj = my_dict()
dict_obj.add('key1', 'value1')
dict_obj.add('key2', 'value2')
dict_obj.add('key1', 'value3')
print(dict_obj)  

>>{'key1': ['value1', 'value3'], 'key2': ['value2']}


dict_obj.remove_value('key1','value3')
print(dict_obj)  

My Out

TypeError: descriptor 'values' of 'dict' object needs an argument

Desired Output

>>{'key1': ['value1'], 'key2': ['value2']}
5
  • 1
    Possible duplicate of Python how to delete a specific value from a dictionary key with multiple values? Commented Aug 5, 2019 at 16:40
  • 2
    Try doing self.values() instead of dict.values()? Or at least dict.values(self). The method values() is an instance method on dict, and you're trying to call it like a class method. Commented Aug 5, 2019 at 16:41
  • @green i change to self.values() , NameError: name 'v' is not defined Commented Aug 5, 2019 at 16:47
  • @maws Double-check what you've named your variables. What did you tell python v was supposed to be, and where did you do so? Commented Aug 5, 2019 at 16:48
  • you want to remove it from self[key].value if value in self[key] Commented Aug 5, 2019 at 16:51

2 Answers 2

0

You've got a couple problems in:

def remove_value(self,key,value):
    for value in dict.values():
        if v in value:
            value.remove(v)
  1. You used dict.values(), not self.values(); the former is trying to call dict.values with no dict instance to operate on
  2. You named two things value, and one replaces the other (while using v without ever naming anything v)

Minimal fix would be:

def remove_value(self,key,v):  # Name argument v to match test and remove
    for value in self.values():  # Call values on self
        if v in value:
            value.remove(v)

Slightly more readable fix (that would also limit removal to the specified key, which I'm guessing was the intent, since you receive a key argument) would be:

def remove_value(self, key, toremove):
    try:
        self[key].remove(toremove)
    except (KeyError, ValueError):
        pass
    else:
        if not self[key]:
            del self[key]

Remove the try/except block if you want non-existent keys or values to raise KeyError or ValueError respectively. Remove the else block if you want to leave a key in place even if all values are removed.

Sign up to request clarification or add additional context in comments.

Comments

0

you need to remove it from self[key].value if value in self[key]:

def remove_value(self,key,value):
    if value in self.get(key, []):
        self[key].remove(value)

But similar to your previous related question, this seems like you'd be better suited using defaultdict than trying to monkeypatch your own dict-like object.

from collections import defaultdict
mydict = defaultdict(list)
mydict['key1'].append('value1')
mydict['key1'].append('value3')
mydict['key2'].append('value2')
if 'value3' in mydict['key1']:
    mydict['key1'].remove('value3')

1 Comment

Note: This will raise KeyError if the key in question doesn't exist; the test prevents the ValueError, but actually triggers the KeyError. You could make it if value in self.get(key, ()): to avoid the KeyError as well. You also left off a : at the end of the if check.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.