2015-10-27 17 views
7

pop sözlüklerde kullanıldığı zaman (bilinen bir anahtar verildiğinde) söz konusu öğeyle sözlüğü kaldırır ve karşılık gelen değeri döndürür. Ama ya anahtarı da istersem?Anahtarını açmanın düzgün bir yolu, sözlükten PAIR değeri?

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

Ama eğer diyelim ki, eminim yukarıdaki fikri takip, en düşük değere sahip anahtar-değer çiftini pop istedim:

Açıkçası, basit vakalarda muhtemelen sadece böyle bir şey yapabileceğini iki kez (tabii ki bir değişkene min çıktı depolayabilir operasyonu yapmak zorunda olduğu gibi ... bunu yapmanın iğrenç

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

... yok, ama yine de tamamen memnun değilim) o. Yani sorum şu: Bunu yapmanın zarif bir yolu var mı? Burada bariz bir numara eksik mi?

+0

mağaza verir özel bir dict oluşturmak Yani burada daha basit bir uygulama

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) 

olduğunu – JBernardo

+1

@JBernardo Bunu düşündüm. Açıkçası daha iyi, ama hala bir tane olmadan daha iyi bir yol olmalı. –

+1

Bir "dict" yerine bir yığın isteyebilirsiniz. 'Heapq' modülüne bakın. – chepner

cevap

3

Python abstract base classes tanımlamak için altyapı sağlar ABC s kullanarak kendinize sözlük nesneyi tanımlayabilirsiniz. , @chepner daha iyi bir seçenek olarak yorumunda önerdi olarak, popitem geçersiz kılabilirsiniz:

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} 

Not Ve sonra ihtiyaca göre piton sözlük nesnelerin pop niteliğini aşırı zaten bir anahtar/değer çifti döndürür. Burada

+0

Önceden bir anahtar/değer çifti döndüren 'popitem''i geçersiz kılmak ve isteğe bağlı bir anahtar bağımsız değişken almasına izin vermek daha iyi olur. – chepner

+0

@chepner Evet, bu daha iyi olurdu. Ben sadece yolu gösterdim. – Kasramvd

+1

Teşekkürler, genel sorun için bir çözüm verdiği kabul edildi. –

3

Bir yığın, tanımladığınız pop-min işlemini destekler. Yine de, öncelikle sözlüğünüzden bir yığın oluşturmanız gerekir.

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

Yanıtladığınız için teşekkür ederiz. Minimum için bu harika, ama bu sadece belli bir anahtar verilen anahtar ve değer, haşhaş daha genel problemin bir örneğiydi (eğer belirsiz ise üzgünüm). İdeal çözüm aynı şeyi diğer kriterlerle de yapabilirdi. –

+0

@ J.F.Sebastian Oops. Bunu biliyordum, ama sonra bir şeyleri test ederken tembelleştim ve 'yığın' sırasının sadece bir yığın tipi gibi değil, 'heapq' işlevlerine uygun bir liste olduğunu unutmuştum. – chepner

1

bir değişkende min` `dan çıkışını istediğiniz öğeyi çıkar ve anahtar-değer çifti

+1

Lütfen biraz açıklama ekleyin! –

+0

tamam wilco Bazı açıklamalar ekleyeceğim – Zion

İlgili konular