शब्दकोश के भीतर न्यूनतम मूल्य के अनुरूप कुंजी प्राप्त करें


304

अगर मेरे पास पायथन डिक्शनरी है, तो मुझे प्रवेश की कुंजी कैसे मिलेगी जिसमें न्यूनतम मूल्य शामिल है?

मैं min()समारोह के साथ कुछ करने के बारे में सोच रहा था ...

इनपुट दिया:

{320:1, 321:0, 322:3}

यह वापस आ जाएगी 321


आपके बताए गए रिटर्न में टाइपो? नहीं तो 321 क्यों? क्या यह 320 नहीं होना चाहिए?
ग्रीनमैट

3
@ मिसेल्फ: ठीक है, अब मैं देखता हूं - जो चाहता है वह प्रवेश की कुंजी है जहां प्रवेश का मूल्य न्यूनतम है। कृपया बेहतर प्रश्न पर ध्यान दें, जैसा कि दूसरों ने स्पष्ट रूप से वैसा ही सोचा जैसा मैंने किया।
ग्रीनमैट

2
डेटा संरचना जागरूकता दिवस: यदि आप कभी भी न्यूनतम तत्व को क्वेरी (या निकालें) करते हैं, तो प्राथमिकता कतार या हीप का उपयोग करने पर विचार करें।
कर्नल पैनिक

जवाबों:


596

सर्वश्रेष्ठ: min(d, key=d.get)- बेकार lambdaअप्रत्यक्ष परत या वस्तुओं या कुंजियों को निकालने का कोई कारण नहीं !


5
@ KarelBílek इसका मतलब है कि आप [11, 22, 33]एक शब्दकोश जैसे "d" को एक उदाहरण के रूप में पारित कर चुके हैं {1: 11, 2:22, 3:33}। 'd.get' एक शब्दकोश के लिए मान्य है, लेकिन सूची के लिए नहीं।
टूलमेकरवेट

9
क्या होगा यदि दो अलग-अलग कुंजी का समान मूल्य हो? और वे दोनों सबसे छोटे मूल्य के होते हैं? आप इसे कैसे लौटा सकते हैं?
user3226932

5
क्या इस तकनीक का उपयोग किया जा सकता है यदि प्रमुख मान सूचियां हैं, उदा: d={"a":[10, None], "b":[20, None]}जहां मिनट की गणना d [कुंजी] [0] से की जाती है?
ट्रेकजॉनसन

4
यह कैसे काम करता है? किस प्रकार का न्यूनतम कार्य है, मैंने सोचा था कि मिनट () ने या तो व्यक्तिगत मूल्यों या सूचियों को तर्क के रूप में लिया। शब्दकोश में सभी प्रविष्टियों पर यह कैसे लूप करता है?
अज़ुरेई

2
min()पहले मान में सॉर्ट किया गया मान वापस करें। कुंजी मानों को सॉर्ट करने का तरीका निर्दिष्ट करती है। key=d.getमतलब सूची को शब्दकोश के मूल्यों द्वारा क्रमबद्ध किया जाएगा।
नटिलास

45

यहाँ एक जवाब है जो वास्तव में ओपी द्वारा पूछे गए समाधान देता है:

>>> d = {320:1, 321:0, 322:3}
>>> d.items()
[(320, 1), (321, 0), (322, 3)]
>>> # find the minimum by comparing the second element of each tuple
>>> min(d.items(), key=lambda x: x[1]) 
(321, 0)

d.iteritems()हालांकि, बड़े शब्दकोशों के लिए उपयोग करना अधिक कुशल होगा।


3
लंबोदर के बजाय आप उपयोग कर सकते हैं operator.itemgetter(1)
फिलिप

2
इसके बजाय लैम्डा उपयोग d.get
टेक्सोम 512

यह कुंजी के रूप में पूछा नहीं लौटाता है, लेकिन (कुंजी, मूल्य) जोड़ी।
एरिक ओ लेबिगोट

14

एकाधिक कुंजियों के लिए जिनका मूल्य सबसे कम है, आप सूची समझ का उपयोग कर सकते हैं:

d = {320:1, 321:0, 322:3, 323:0}

minval = min(d.values())
res = [k for k, v in d.items() if v==minval]

[321, 323]

एक समतुल्य कार्यात्मक संस्करण:

res = list(filter(lambda x: d[x]==minval, d))

1
आपका उत्तर बहुत उपयोगी है और अन्य शायद सहमत हैं: स्वीकृत उत्तर में उस मामले के लिए कई टिप्पणियां देखें। हालाँकि, मुझे इसे खोजने के लिए दो बार वापस आने की आवश्यकता थी: क्या आप स्वीकृत उत्तर को संपादित करने के प्रस्ताव पर विचार करेंगे? तुम्हारा वास्तव में पूरक है।
jmon12


6
>>> d = {320:1, 321:0, 322:3}
>>> min(d, key=lambda k: d[k]) 
321

@SilentGhost, @ blob8108: D'oh! कॉपी-एंड-पेस्ट स्नैफू। अब तय हो गया।
डैनियल स्टटज़बेक

ठीक समाधान मुझे लगता है, लेकिन अनाम फ़ंक्शन केवल अप्रत्यक्ष की एक परत जोड़ता है: key=d.getबेहतर है।
एरिक ओ लेबिगोट

6

उस मामले के लिए जहां आपके पास कई न्यूनतम कुंजी हैं और इसे सरल रखना चाहते हैं

def minimums(some_dict):
    positions = [] # output variable
    min_value = float("inf")
    for k, v in some_dict.items():
        if v == min_value:
            positions.append(k)
        if v < min_value:
            min_value = v
            positions = [] # output variable
            positions.append(k)

    return positions

minimums({'a':1, 'b':2, 'c':-1, 'd':0, 'e':-1})

['e', 'c']

4

यदि आप सुनिश्चित नहीं हैं कि आपके पास कई न्यूनतम मूल्य नहीं हैं, तो मैं सुझाव दूंगा:

d = {320:1, 321:0, 322:3, 323:0}
print ', '.join(str(key) for min_value in (min(d.values()),) for key in d if d[key]==min_value)

"""Output:
321, 323
"""

3

संपादित करें: यह न्यूनतम कुंजी के बारे में ओपी के मूल प्रश्न का उत्तर है, न कि न्यूनतम उत्तर।


आप keysफ़ंक्शन का उपयोग करके तानाशाह की चाबी प्राप्त कर सकते हैं , और आप minउस सूची के न्यूनतम का उपयोग करने के बारे में सही हैं ।


वास्तव में एक नीच के योग्य नहीं, क्योंकि पोस्टर का मूल प्रश्न उतना स्पष्ट नहीं था जितना कि हो सकता है।
ग्रीनमैट

@ Space_C0wb0y: शायद आप इतना ध्यान में तरह कि ओपी मतलब कुछ अलग करने के लिए अपने सवाल संपादित किया जा सकता है, के बाद मैंने जवाब
एली बेन्देर्स्क्य

3

एक ही न्यूनतम मान के साथ कई कुंजियों के मुद्दे को संबोधित करने के लिए एक और दृष्टिकोण:

>>> dd = {320:1, 321:0, 322:3, 323:0}
>>>
>>> from itertools import groupby
>>> from operator import itemgetter
>>>
>>> print [v for k,v in groupby(sorted((v,k) for k,v in dd.iteritems()), key=itemgetter(0)).next()[1]]
[321, 323]

2

minएक इटरेटर के साथ उपयोग करें (अजगर 3 उपयोग के itemsबजाय iteritems); लैम्बडा के बजाय itemgetterऑपरेटर से उपयोग करें , जो लैम्ब्डा की तुलना में तेज है।

from operator import itemgetter
min_key, _ = min(d.iteritems(), key=itemgetter(1))


1

मैंने तुलना की कि निम्नलिखित तीन विकल्प कैसे प्रदर्शन करते हैं:

    import random, datetime

myDict = {}
for i in range( 10000000 ):
    myDict[ i ] = random.randint( 0, 10000000 )



# OPTION 1

start = datetime.datetime.now()

sorted = []
for i in myDict:
    sorted.append( ( i, myDict[ i ] ) )
sorted.sort( key = lambda x: x[1] )
print( sorted[0][0] )

end = datetime.datetime.now()
print( end - start )



# OPTION 2

start = datetime.datetime.now()

myDict_values = list( myDict.values() )
myDict_keys = list( myDict.keys() )
min_value = min( myDict_values )
print( myDict_keys[ myDict_values.index( min_value ) ] )

end = datetime.datetime.now()
print( end - start )



# OPTION 3

start = datetime.datetime.now()

print( min( myDict, key=myDict.get ) )

end = datetime.datetime.now()
print( end - start )

नमूना उत्पादन:

#option 1
236230
0:00:14.136808

#option 2
236230
0:00:00.458026

#option 3
236230
0:00:00.824048

0

एक आदेश योग्य वर्ग बनाने के लिए आपको 6 विशेष कार्यों को ओवरराइड करना होगा, ताकि इसे मिनट () फ़ंक्शन द्वारा बुलाया जा सके

इन विधियों के __lt__ , __le__, __gt__, __ge__, __eq__ , __ne__क्रम में वे कम से कम या बराबर, से अधिक, अधिक से अधिक या बराबर, बराबर, नहीं के बराबर हैं। उदाहरण के लिए आपको __lt__निम्नानुसार लागू करना चाहिए :

def __lt__(self, other):
  return self.comparable_value < other.comparable_value

तो आप निम्न के रूप में न्यूनतम समारोह का उपयोग कर सकते हैं:

minValue = min(yourList, key=(lambda k: yourList[k]))

यह मेरे लिए काम किया।


0
min(zip(d.values(), d.keys()))[1]

मान और कुंजियों वाले टुपल्स का पुनरावृत्त बनाने के लिए ज़िप फ़ंक्शन का उपयोग करें। फिर इसे एक मिनी फ़ंक्शन के साथ लपेटें जो पहली कुंजी के आधार पर न्यूनतम लेता है। यह एक टपल युक्त (मान, की) जोड़ी देता है। संबंधित कुंजी पाने के लिए [1] के सूचकांक का उपयोग किया जाता है


2
हालांकि यह कोड प्रश्न का उत्तर दे सकता है, लेकिन यह कोड क्यों और / या इस बारे में अतिरिक्त संदर्भ प्रदान करता है कि यह प्रश्न इसके दीर्घकालिक मूल्य में सुधार करता है।
β.βοιτ.βε

@ @.βοιτ.βε बेहतर है?
राज

-1
# python 
d={320:1, 321:0, 322:3}
reduce(lambda x,y: x if d[x]<=d[y] else y, d.iterkeys())
  321

6
1) कम करना आमतौर पर itertools की तुलना में धीमी है। 2) कम करने के अधिकांश कार्यान्वयन किसी भी या सभी के साथ सरल हो सकते हैं। 3) मैं GvR के लिए एक विशाल मुखपत्र हूं। 4) ऑपरेटर मॉड्यूल सबसे सरल लैम्ब्डा को अनावश्यक बनाता है, और जटिल लैम्ब्डा को वैसे भी वास्तविक कार्यों के रूप में परिभाषित किया जाना चाहिए। शायद मैं सिर्फ कार्यात्मक प्रोग्रामिंग से डरता हूं। ;)
माइक जूल

@ मिक्स्ड: मुझे और बताओ। क्या gvr है और ऑपरेटर मॉड्यूल क्या है? क्या आप लिंक पोस्ट कर सकते हैं? मैं दूसरों को जान सकता हूं, लेकिन मैं अभी भी अजगर में सिर्फ एक मध्यवर्ती हूं। सीखने को इच्छुक! :-)
eruciform

जीवीआर गुइडो वैन रोसुम है, जो जीवन के लिए अजगर का उदार तानाशाह है। यहाँ से एक पाँच साल पुरानी पोस्ट बता रही है कि लिस्प-आइम्स (नक्शा, फ़िल्टर, कम, लैम्ब्डा) में अजगर को आगे बढ़ने की जगह नहीं है, और वे कारण आज भी सही हैं। ऑपरेटर मॉड्यूल में सदस्यों को निकालने के लिए प्रतिस्थापन हैं : "लैम्बडा x: x [1]" की तुलना में "आइटमगेटर (1)" एक चरित्र लंबा है और यकीनन समझने में अधिक समय लेता है। मैं अंतरिक्ष से बाहर हूँ, लेकिन सवाल पूछ रहा हूँ!
माइक जूल

@ मिक्स्ड: सेब पर पहले काटने चाहते हैं? stackoverflow.com/questions/3292481/…
eruciform

उनकी वास्तव में ( min()) में निर्मित कुछ को फिर से लागू करने की आवश्यकता नहीं है ।
एरिक ओ लेबिगोट

-8

क्या यह वही है जिसको तुम खोज रहे हो?

d = dict()
d[15.0]='fifteen'
d[14.0]='fourteen'
d[14.5]='fourteenandhalf'

print d[min(d.keys())]

प्रिंट 'चौदह'


8
-1: सवाल क्या नहीं पूछा। आप न्यूनतम कुंजी के साथ मान लौटा रहे हैं, ओपी न्यूनतम मूल्य के साथ कुंजी चाहता है
ब्रायन एस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.