弹出键的整洁方式,从字典中值 PAIR?
Posted
技术标签:
【中文标题】弹出键的整洁方式,从字典中值 PAIR?【英文标题】:Neat way of popping key, value PAIR from dictionary? 【发布时间】:2016-01-27 01:49:14 【问题描述】:pop
是一个很棒的小函数,当用于字典时(给定一个已知键),它会从字典中删除具有该键的项目并返回相应的值。但如果我也想要钥匙怎么办?
显然,在简单的情况下,我可能只需要这样做:
pair = (key, some_dict.pop(key))
但是,如果我想弹出具有最低值的键值对,按照上述想法,我将不得不这样做......
pair = (min(some_dict, key=some.get), some_dict.pop(min(some_dict, key=some_dict.get)))
... 这太可怕了,因为我必须执行两次操作(显然我可以将来自 min
的输出存储在一个变量中,但我仍然对此并不完全满意)。所以我的问题是:有没有一种优雅的方式来做到这一点?我在这里错过了一个明显的技巧吗?
【问题讨论】:
将min
的输出存储在一个变量中
@JBernardo 我已经想到了。显然更好,但我仍然觉得应该没有更好的方法。
你可能想要一个堆,而不是dict
。请参阅heapq
模块。
你为什么不喜欢使用变量?
在我看来,如果有办法,那将是 some_dict.popitem()
的一个可选参数 - 但文档在那里没有给出任何参数,所以我认为没有办法。
【参考方案1】:
这是一个更简单的实现
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)
所以这里我们创建了一个自定义的dict
,它会弹出你想要的项目并给出键值对
【讨论】:
请补充说明!【参考方案2】:您可以使用 python ABCs 定义自己的字典对象,它提供了定义 abstract base classes 的基础设施。然后根据需要重载python字典对象的pop
属性:
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__)
演示:
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
注意:正如 @chepner 在评论中建议的更好的选择,您可以覆盖 popitem
,它已经返回一个键/值对。
【讨论】:
最好覆盖popitem
,它已经返回了一个键/值对,并允许它接受一个可选的键参数。
@chepner 是的,这样会更好。我只是指路了。
谢谢,接受,因为它解决了一般问题。
我想按照 JBernado 的建议将密钥存储在变量中比实现一个全新的类更可取。【参考方案3】:
堆支持您描述的 pop-min 操作。不过,您需要先从字典中创建一个堆。
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)
【讨论】:
感谢您的回答。这对于最小值来说很好,但这只是一个更普遍的问题的例子,即在给定某个键的情况下弹出键和值的更普遍问题(如果不清楚,请抱歉)。理想的解决方案可以用其他标准做同样的事情。 @J.F.Sebastian 哎呀。我知道这一点,但是在测试某些东西时我变得懒惰并忘记了heap
只是一个列表,其顺序适用于 heapq
函数,而不是不同堆类型的实例。以上是关于弹出键的整洁方式,从字典中值 PAIR?的主要内容,如果未能解决你的问题,请参考以下文章