2015-10-27 58 views
7

pop是一個很棒的小函數,它在字典上使用時(給定一個已知鍵)從字典中刪除具有該鍵的項,並返回相應的值。但是如果我想要鑰匙呢?從字典中彈出密鑰,值PAIR的乾淨方式?

顯然,在簡單的情況下,我很可能只是做這樣的事情:

pair = (key, some_dict.pop(key)) 

但如果說,我想彈出鍵 - 值對具有最低值,按照上面的想法,我會要做到這一點...

pair = (min(some_dict, key=some.get), some_dict.pop(min(some_dict, key=some_dict.get))) 

...這是可怕的,因爲我必須做的操作兩次(很明顯,我可以存儲來自min在一個變量輸出,但我仍然不完全滿意那)。所以我的問題是:是否有一個優雅的方式來做到這一點?我錯過了一個顯而易見的把戲嗎?

+0

店從'min'輸出在一個變量 – JBernardo

+1

@JBernardo我曾想到這一點。這顯然更好,但我仍然覺得應該有一個更好的方式沒有一個。 –

+1

你可能想要一堆,而不是'dict'。查看'heapq'模塊。 – chepner

回答

3

您可以使用Python ABC S的提供了定義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,它已經返回一個鍵/值對。

+0

重寫'popitem'會更好一些,它已經返回一個鍵/值對,並允許它帶一個可選的鍵參數。 – chepner

+0

@chepner是的,那會更好。我只是展示了道路。 – Kasramvd

+1

謝謝,接受,因爲它解決了一般問題。 –

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) 
+0

感謝您的回答。這對於最低限度是很好的,但這只是一個更普遍的問題,即在某個關鍵點(如果不清楚的情況下,很抱歉)彈出關鍵字和值都是一個例子。理想的解決方案將能夠與其他標準做同樣的事情。 –

+0

@ J.F.Sebastian Oops。我知道這一點,但是在測試某些東西時,我感到很懶,並忘記了'heap'只是一個順序符合heapq函數的列表,而不是一個獨立堆類型的實例。 – chepner

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彈出你想要的物品,並給出了鍵值對

+1

請添加一些解釋! –

+0

好的wilco我會添加一些解釋 – Zion

相關問題