pop
is a great little function that, when used on dictionaries (given a known key) removes the item with that key from the dictionary and also returns the corresponding value. But what if I want the key as well?
Obviously, in simple cases I could probably just do something like this:
pair = (key, some_dict.pop(key))
But if, say, I wanted to pop the key-value pair with the lowest value, following the above idea I would have to do this...
pair = (min(some_dict, key=some.get), some_dict.pop(min(some_dict, key=some_dict.get)))
... which is hideous as I have to do the operation twice (obviously I could store the output from min
in a variable, but I'm still not completely happy with that). So my question is: Is there an elegant way to do this? Am I missing an obvious trick here?
You can define yourself dictionary object using python ABCs which provides the infrastructure for defining abstract base classes. And then overload the pop
attribute of python dictionary objects based on your need:
from collections import Mapping
class MyDict(Mapping):
def __init__(self, *args, **kwargs):
self.update(dict(*args, **kwargs))
def __setitem__(self, key, item):
self.__dict__[key] = item
def __getitem__(self, key):
return self.__dict__[key]
def __delitem__(self, key):
del self.__dict__[key]
def pop(self, k, d=None):
return k,self.__dict__.pop(k, d)
def update(self, *args, **kwargs):
return self.__dict__.update(*args, **kwargs)
def __iter__(self):
return iter(self.__dict__)
def __len__(self):
return len(self.__dict__)
def __repr__(self):
return repr(self.__dict__)
Demo:
d=MyDict()
d['a']=1
d['b']=5
d['c']=8
print d
{'a': 1, 'c': 8, 'b': 5}
print d.pop(min(d, key=d.get))
('a', 1)
print d
{'c': 8, 'b': 5}
Note : As @chepner suggested in comment as a better choice you can override popitem
, which already returns a key/value pair.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With