किसी सूची में अधिकतम मूल्य और उसके सूचकांक का पता लगाने का पायथोनिक तरीका?


151

यदि मुझे किसी सूची में अधिकतम मूल्य चाहिए, तो मैं बस लिख सकता हूं max(List), लेकिन क्या होगा यदि मुझे अधिकतम मूल्य के सूचकांक की आवश्यकता है?

मैं कुछ इस तरह लिख सकता हूं:

maximum=0
for i,value in enumerate(List):
    if value>maximum:
        maximum=value
        index=i

लेकिन यह मुझे थकाऊ लगता है।

और अगर मैं लिखता हूँ:

List.index(max(List))

फिर यह सूची को दो बार प्रसारित करेगा।

क्या कोई बेहतर तरीका है?


"यह दो बार सूची पास करेगा" से आपका क्या मतलब है? List.index (अधिकतम (सूची)) मेरे लिए काम करता है।
mwcz

14
@mwc: यह अधिकतम मूल्य निर्धारित करने के लिए एक बार सूची को पुन: व्यवस्थित करेगा, फिर उस मूल्य के सूचकांक को खोजने के लिए इसे दूसरी बार पुन: व्यवस्थित करेगा।

10
यदि अधिकतम मूल्य डुप्लिकेट हैं, तो list.index () समस्याग्रस्त नहीं होगा?
लोगन यांग

@LoganYang हाँ समान मूल्य वाले दो आइटम हो सकते हैं।
फ्लोरियन

यदि आदेश महत्वपूर्ण नहीं है, तो आप List.sort () [- 1] जैसे कुछ कर सकते हैं
फ्लोरियन

जवाबों:


186

उदाहरण के लिए, कई विकल्प हैं:

import operator
index, value = max(enumerate(my_list), key=operator.itemgetter(1))

2
आह, मैंने इसे अन्य स्थानों पर देखा है, लेकिन मैंने सोचा कि यह केवल एक मूल्य लौटाएगा, टुप नहीं।
सनी88

1
@ सनी88: keyफ़ंक्शन का उपयोग केवल यह तय करने के लिए किया जाता है कि कौन सा तत्व अधिकतम है। तत्व नहीं बदले हैं।
स्वेन मार्नाच

6
@SvenMarnach क्यों नहीं key=lambda e: e[1]इसके बजाय आयात से बचें?
जीवनशैली

8
@lifebalance का उपयोग करना itemgetter()तेज़ है, और आयात से बचना लक्ष्य का पीछा करने के लायक नहीं है। बाहरी निर्भरता से बचना कुछ मामलों में सार्थक हो सकता है, लेकिन मानक पुस्तकालय से आयात एक गैर-मुद्दा है।
स्वेन मार्नाच

324

मुझे लगता है कि स्वीकृत उत्तर बहुत अच्छा है, लेकिन आप इसे स्पष्ट रूप से क्यों नहीं करते हैं? मुझे लगता है कि अधिक लोग आपके कोड को समझेंगे, और वह पीईपी 8 के साथ समझौता करेगा:

max_value = max(my_list)
max_index = my_list.index(max_value)

यह विधि भी स्वीकृत उत्तर की तुलना में लगभग तीन गुना तेज है:

import random
from datetime import datetime
import operator

def explicit(l):
    max_val = max(l)
    max_idx = l.index(max_val)
    return max_idx, max_val

def implicit(l):
    max_idx, max_val = max(enumerate(l), key=operator.itemgetter(1))
    return max_idx, max_val

if __name__ == "__main__":
    from timeit import Timer
    t = Timer("explicit(l)", "from __main__ import explicit, implicit; "
          "import random; import operator;"
          "l = [random.random() for _ in xrange(100)]")
    print "Explicit: %.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000)

    t = Timer("implicit(l)", "from __main__ import explicit, implicit; "
          "import random; import operator;"
          "l = [random.random() for _ in xrange(100)]")
    print "Implicit: %.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000)

मेरे कंप्यूटर में चलने के परिणाम:

Explicit: 8.07 usec/pass
Implicit: 22.86 usec/pass

अन्य सेट:

Explicit: 6.80 usec/pass
Implicit: 19.01 usec/pass

3
यह तेजी से होने की उम्मीद नहीं की थी। जब मैं x को "l = [random.random () for _ in xrange (10000000) + + [2] से बदल देता हूं तब भी यह तेज होता है, जो यह गारंटी देता है कि अंतिम तत्व सबसे बड़ा है।
सनी

14
@ सनी88: संख्याओं की एक सरल सूची के लिए, सरल दृष्टिकोण तेज है। यदि आप इस मामले में प्रदर्शन के बाद हैं, तो मैं उपयोग करने का सुझाव numpy.argmax()दूंगा, जो मेरी मशीन पर 30 गुना तेज है। यदि सूची में केवल संख्याओं की तुलना में अधिक जटिल वस्तुएं हैं, तो मेरे उत्तर में दृष्टिकोण तेज हो सकता है। उस दृष्टिकोण का ऊँचा लाभ यह है कि इसका उपयोग मनमाने ढंग से चलने वालों के लिए किया जा सकता है, न केवल सूचियों के लिए।
स्वेन मार्नाच

@ स्वेन-मार्नाच तेजी से सुन्न होगा, अगर मुझे अपनी सूची को पहले एक खस्ताहाल सरणी में बदलना था? क्या यह सरल उदाहरण [0,1,0] के लिए तेज़ होगा?
tommy.carstensen

1
@ स्वेन-मार्नाच मैंने अभी-अभी चेक किया है। numpy.argmax अब तक की सबसे धीमी विधि है, और यह गलत उत्तर देती है, यदि सरणी में फ़्लोट्स या पूर्णांक के बजाय तार होते हैं।
tommy.carstensen

9
यदि अधिकतम मूल्य डुप्लिकेट हैं, तो list.index () समस्याग्रस्त नहीं होगा?
लोगन यांग

20

यह उत्तर @Escualo की तुलना में 33 गुना तेज है, यह मानते हुए कि सूची बहुत बड़ी है, और यह मानते हुए कि यह पहले से ही np.array () है। मुझे परीक्षण रनों की संख्या को कम करना पड़ा क्योंकि परीक्षण केवल 100 नहीं बल्कि 10000000 तत्वों को देख रहा है।

import random
from datetime import datetime
import operator
import numpy as np

def explicit(l):
    max_val = max(l)
    max_idx = l.index(max_val)
    return max_idx, max_val

def implicit(l):
    max_idx, max_val = max(enumerate(l), key=operator.itemgetter(1))
    return max_idx, max_val

def npmax(l):
    max_idx = np.argmax(l)
    max_val = l[max_idx]
    return (max_idx, max_val)

if __name__ == "__main__":
    from timeit import Timer

t = Timer("npmax(l)", "from __main__ import explicit, implicit, npmax; "
      "import random; import operator; import numpy as np;"
      "l = np.array([random.random() for _ in xrange(10000000)])")
print "Npmax: %.2f msec/pass" % (1000  * t.timeit(number=10)/10 )

t = Timer("explicit(l)", "from __main__ import explicit, implicit; "
      "import random; import operator;"
      "l = [random.random() for _ in xrange(10000000)]")
print "Explicit: %.2f msec/pass" % (1000  * t.timeit(number=10)/10 )

t = Timer("implicit(l)", "from __main__ import explicit, implicit; "
      "import random; import operator;"
      "l = [random.random() for _ in xrange(10000000)]")
print "Implicit: %.2f msec/pass" % (1000  * t.timeit(number=10)/10 )

मेरे कंप्यूटर पर परिणाम:

Npmax: 8.78 msec/pass
Explicit: 290.01 msec/pass
Implicit: 790.27 msec/pass

बस स्पष्ट करने के लिए: स्पीडअप सिर्फ सी सी सी लागू करने के कारण है बनाम शुद्ध अजगर? या शुद्ध अजगर का उपयोग कर @ Escualo के जवाब में कोई सुधार लाने का कोई तरीका है?
अधिकतम

यदि कोई अजगर 3.6 का उपयोग करना चाहे, तो कुछ ऐसा कर सकता है: "l = np.array ([random.random (in रेंज में _ 10000000)])") प्रिंट (f "Npmax: {(1000 /)) समय (संख्या = 10) / 10): 5.2f} मिसेक / पास ")
पीरोट सेजदा

यह 2.7 पर था
portforwardpodcast

1
ठीक है, numpy.argmaxजब तक आप इसे एक मानक अजगर सूची को संसाधित करने नहीं देते, तब तक आश्चर्यजनक दिखता है । तब गति स्पष्ट और निहित संस्करण के बीच होती है। मुझे लगता np.arrayहै कि यह केवल एक सूची नहीं बनाता है, लेकिन इसमें कुछ अतिरिक्त जानकारी है - उदाहरण के लिए न्यूनतम और अधिकतम मान (बस एक परिकल्पना)।
मिरोस्लाव ओपोका

18

पायथन की अंतर्निहित लाइब्रेरी के साथ, यह बहुत आसान है:

a = [2, 9, -10, 5, 18, 9] 
max(xrange(len(a)), key = lambda x: a[x])

यह कस्टम फ़ंक्शन का उपयोग करके maxसूची में सबसे बड़ी संख्या को खोजने के लिए कहता है , जो कहता है कि वास्तव में है , वास्तव में है , आदि।[0, 1, 2, ..., len(a)]lambda x: a[x]0219


पायथन 3 में, कोई व्यवस्था नहीं है, यदि आप कोड लिखना चाहते हैं जो पायथन 2 और पायथन 3 दोनों के लिए चलेगा, तो आपको रेंज () का उपयोग करना चाहिए।
चुंडे हुआंग

10
max([(v,i) for i,v in enumerate(my_list)])

यह बेहतर है क्योंकि आप इसे टपल के अलावा किसी अन्य चीज़ के साथ उपयोग करने के लिए अनुकूलित कर सकते हैं।
wieczorek1990

यह वास्तव में कैसे काम करता है? क्या आप प्रक्रिया को तोड़ सकते हैं?
clabe45

Hi @ clabe45, यह my_list को tuples (v, i) की सूची में परिवर्तित करता है, जहाँ v मेरी सूची का प्रत्येक आइटम है और मैं संवाददाता इंडेक्स है, फिर इसे अधिकतम मान (और इसके संबंधित सूचकांक के साथ) के साथ tuple मिलता है
लुइस सोबरेसेवा

4
धन्यवाद, क्या आप संभवतः उत्तर में पोस्ट कर सकते हैं? और अधिकतम मूल्य की गणना करते समय maxहर टपल के पहले आइटम ( v) को कैसे जाना जाता है?
क्लैब 4545

1
@ clabe45 हो सकता है कि यह उत्तर बहुत देर से आए, लेकिन दूसरों के लिए (मेरे जैसे) जो अब इस धागे में आए हैं, यहां: stackoverflow.com/questions/18296755/… एक स्पष्टीकरण है। यह पंक्ति नहीं है: "डिफ़ॉल्ट रूप से अधिकतम सूचकांक द्वारा वस्तुओं की तुलना की जाएगी, यदि पहला सूचकांक समान है तो यह दूसरे सूचकांक की तुलना करेगा।" इसलिए मैंने इसे सूची के साथ आज़माया: l = [1,1,1] और उसके बाद अधिकतम ([(v, i) i, v के लिए enumerate (l)] में) और यह मुझे पहले 1 नहीं बल्कि अंतिम देता है परिणाम के रूप में एक: (1,2)। मुझे उम्मीद है कि यह :)
अनुपम जैन

10

मैं एक बहुत ही सरल तरीका सुझाऊंगा:

import numpy as np
l = [10, 22, 8, 8, 11]
print(np.argmax(l))
print(np.argmin(l))

आशा करता हूँ की ये काम करेगा।


4
max([(value,index) for index,value in enumerate(your_list)]) #if maximum value is present more than once in your list then this will return index of the last occurrence

यदि एक से अधिक बार वर्तमान में अधिकतम मूल्य और आप सभी सूचकांक प्राप्त करना चाहते हैं,

max_value = max(your_list)
maxIndexList = [index for index,value in enumerate(your_list) if value==max(your_list)]

1
हाँ। मैंने लगभग एक उत्तर पोस्ट किया है, लेकिन फिर मैंने देखा कि आपकी सूची में एक ही तर्क के साथ एक ही समाधान पहले से ही था।
WalyKu

2

हो सकता है कि आपको किसी तरह की सूची की आवश्यकता हो?

इसे इस्तेमाल करे:

your_list = [13, 352, 2553, 0.5, 89, 0.4]
sorted_list = sorted(your_list)
index_of_higher_value = your_list.index(sorted_list[-1])

1. छंटनी में उच्च समय जटिलता होती है। 2. sorted_listलेकिन अनुक्रमित नहीं करता है मूल्यों, इसलिए यह काम नहीं करेगा।

1

इस धागे को पुनर्जीवित करने के लिए खेद है, लेकिन मुझे लगा कि मेरा तरीका जोड़ने लायक था।

इस उदाहरण 'सूची' में सूची का नाम

list.sort()
print(list[-1])

यह आसान के रूप में सूची में उच्चतम मूल्य मुद्रित करेगा!

list.sort()ASCII तालिका में आइटम के मूल्य द्वारा सूची को सॉर्ट करें , इसलिए प्रभावी रूप से सूची को सबसे कम से सबसे अधिक तक सॉर्ट करें। मैं तब सूची में अंतिम मान (जो सबसे बड़ी संख्या होगी) का उपयोग करके प्रिंट करता हूंprint(list[-1])

उम्मीद है की यह मदद करेगा!


5
हम इस तरह से सूचकांक प्राप्त नहीं कर सकते हैं
toing_toing

-1

यहाँ पायथन के अंतर्निहित कार्यों का उपयोग करके आपके प्रश्न का पूरा समाधान दिया गया है:

# Create the List
numbers = input("Enter the elements of the list. Separate each value with a comma. Do not put a comma at the end.\n").split(",") 

# Convert the elements in the list (treated as strings) to integers
numberL = [int(element) for element in numbers] 

# Loop through the list with a for-loop

for elements in numberL:
    maxEle = max(numberL)
    indexMax = numberL.index(maxEle)

print(maxEle)
print(indexMax)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.