Neat way of popping key, value PAIR from dictionary?

末鹿安然 提交于 2019-12-30 18:09:08

问题


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?


回答1:


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.




回答2:


A heap supports the pop-min operation you describe. You'll need to create a heap from your dictionary first, though.

import heapq
# Must be two steps; heapify modifies its argument in-place.
# Reversing the key and the value because the value will actually be
# the "key" in the heap. (Or rather, tuples are compared 
# lexicographically, so put the value in the first position.)
heap = [(v, k) for k, v in some_dict.items()]
heapq.heapify(heap)

# Get the smallest item from the heap
value, key = heapq.heappop(heap)



回答3:


here is a simpler implementation

class CustomDict(dict):
    def pop_item(self, key):
        popped = {key:self[key]} #save "snapshot" of the value of key before popping
        self.pop(key)
        return popped

a = CustomDict()
b = {"hello":"wassup", "lol":"meh"}
a.update(b)
print(a.pop_item("lol"))
print(a)

So here we create a custom dict that pops the item you want and gives out the key-value pair



来源:https://stackoverflow.com/questions/33371558/neat-way-of-popping-key-value-pair-from-dictionary

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!