किसी सूची में अधिकतम () / मिनट () का उपयोग करके लौटे अधिकतम या न्यूनतम आइटम का सूचकांक प्राप्त करना


464

मैं पायथन के उपयोग कर रहा हूँ maxऔर minकार्यों सूची में एक अल्पमहिष्ठ एल्गोरिथ्म के लिए, और मैं मूल्य के सूचकांक द्वारा वापस की जरूरत है max()या min()। दूसरे शब्दों में, मुझे यह जानना होगा कि किस कदम ने अधिकतम (पहले खिलाड़ी की बारी पर) या मिनट (दूसरे खिलाड़ी) मूल्य का उत्पादन किया।

for i in range(9):
    newBoard = currentBoard.newBoardWithMove([i / 3, i % 3], player)

    if newBoard:
        temp = minMax(newBoard, depth + 1, not isMinLevel)  
        values.append(temp)

if isMinLevel:
    return min(values)
else:
    return max(values)

मुझे न्यूनतम या अधिकतम मूल्य के वास्तविक सूचकांक को वापस करने में सक्षम होना चाहिए, न कि केवल मूल्य।


32
Builtin divmodकहने के लिए होने को रोकने के लिए मौजूद है [i / 3, i % 3]ज्यादा।
माइक ग्राहम

जवाबों:


416
अगर है
    वापसी मान .index (न्यूनतम (मान))
अन्य:
    वापसी मान .index (अधिकतम (मान))

38
@ केविनग्रिफिन, ध्यान दें कि यह आपको न्यूनतम / अधिकतम की संभवतः कई घटनाओं में से एक है। यह वह नहीं हो सकता है जो आप चाहते हैं, उदाहरण के लिए यदि आपके लाभ को दो समान तरीके से बढ़ाना संभव है, लेकिन उनमें से एक दूसरे खिलाड़ी को अधिक नुकसान पहुंचाता है। मुझे नहीं पता कि यह एक ऐसा मामला है जिस पर आपको विचार करने की आवश्यकता है।
माइक ग्राहम

89
@ कश्यप यह वास्तव में ओ (एन) है, ओ नहीं (एन ^ 2)। न्यूनतम मामले में, पहले मिनट (मान) का मूल्यांकन किया जाता है, जो O (N) है, फिर मान .index () कहलाता है, जो O (N) भी है। O (N) + O (N) = O (N)। सूचकांक का तर्क केवल एक बार मूल्यांकन किया जाता है। यह इसके बराबर है:tmp = min(values); return values.index(tmp)
टॉम करेजेस

@ जब तत्वों की पुनरावृत्ति होती है तो बहुत php क्या करना है?
शशि तुंगा

@ शशी तुंगा [सूची] .index () किसी चीज़ की केवल पहली घटना लौटाती है, यह गारंटी नहीं है कि यह अनन्य है, सूची के भीतर न्यूनतम मूल्य अद्वितीय नहीं हो सकता है
स्कॉट एंडरसन

470

कहें कि आपके पास एक सूची है values = [3,6,1,5], और index_min = 2इस मामले में सबसे छोटे तत्व के सूचकांक की आवश्यकता है ।

itemgetter()अन्य उत्तरों में प्रस्तुत समाधान से बचें , और इसके बजाय उपयोग करें

index_min = min(range(len(values)), key=values.__getitem__)

क्योंकि इसका import operatorउपयोग करने के लिए न तो आवश्यकता होती है enumerate, और न ही उपयोग करने वाले समाधान की तुलना में यह हमेशा तेज (नीचे बेंचमार्क) होता है itemgetter()

यदि आप सुन्न सरणियों के साथ काम कर रहे हैं या numpyनिर्भरता के रूप में खर्च कर सकते हैं , तो उपयोग करने पर भी विचार करें

import numpy as np
index_min = np.argmin(values)

यदि आप इसे शुद्ध पायथन सूची में लागू करते हैं तो भी यह पहले समाधान से अधिक तेज़ होगा:

  • यह कुछ तत्वों (मेरी मशीन पर लगभग २ ** ४ तत्वों) से बड़ा है
  • आप एक शुद्ध सूची से numpyसरणी में मेमोरी कॉपी का खर्च उठा सकते हैं

जैसा कि यह मानदंड बताता है: यहाँ छवि विवरण दर्ज करें

मैंने अपनी मशीन पर पायथन 2.7 के साथ दो समाधान ऊपर (नीला: शुद्ध अजगर, पहला समाधान) (लाल, खस्ता समाधान) और मानक समाधान के लिए itemgetter()(काला, संदर्भ समाधान) के लिए चलाया है । अजगर 3.5 के साथ एक ही बेंचमार्क से पता चला है कि तरीकों की तुलना ऊपर प्रस्तुत किए गए अजगर 2.7 मामले के बिल्कुल समान है


एक बहुत मजबूत +1। मुझे प्रस्तावित समाधानों के बेंचमार्किंग और आपके द्वारा संक्षेप में लिखे गए अंगूठे के नियमों से प्यार है। जैसा कि मैंने नीचे एक और उत्तर में सुझाव दिया है, क्या आप अपना परीक्षण कोड प्रदान कर सकते हैं (या लिंक कर सकते हैं) ताकि अन्य लोग आपके परिणामों को पुन: उत्पन्न कर सकें? मशीनें और पुस्तकालय समय के साथ बदलते हैं, और यह अन्य समाधानों की तुलना करने की अनुमति देता है।
रकुराई

3
मुझे लगता है कि कोई टाइपो हो सकता है: xrange। यह सीमा नहीं होनी चाहिए?
लिंडसे फाउलर

6
@ लिंडसेफ़ॉवलर xrange()अब पदावनत हो गया है, आप उपयोग कर सकते हैंrange()
davide

np.argmin फ़्लोट्स के लिए काम नहीं करता है। केवल पहला सुझाव किट्स और फ्लोट्स पर काम करता है।
जिम्ह

मुझे लगता है कि आप गलत हैं, कोशिश करें import numpy as np; x = [2.3, -1.4]; np.argmin(x)। आप देखेंगे कि argminझांकियों पर भी काम होता है
gg349

332

यदि आप सूची में आइटमों की गणना करते हैं, लेकिन सूची के मूल मूल्यों पर न्यूनतम / अधिकतम प्रदर्शन करते हैं, तो आप उसी समय न्यूनतम / अधिकतम सूचकांक और मूल्य पा सकते हैं। इस तरह:

import operator
min_index, min_value = min(enumerate(values), key=operator.itemgetter(1))
max_index, max_value = max(enumerate(values), key=operator.itemgetter(1))

इस तरह सूची केवल एक बार मिनट (या अधिकतम) के लिए निकाली जाएगी।


110
या एक लैम्ब्डा का उपयोग करें:key=lambda p: p[1]
scry करें

116

यदि आप संख्याओं की सूची के भीतर अधिकतम का सूचकांक ढूंढना चाहते हैं (जो कि आपका मामला लगता है), तो मेरा सुझाव है कि आप संख्यात्मक उपयोग करें:

import numpy as np
ind = np.argmax(mylist)

अधिकतम मूल्यों की कई घटनाओं के मामले में, पहली घटना के अनुरूप सूचकांक लौटा दिए जाते हैं।
कोहेन्सियस

41

संभवतः एक सरल समाधान मूल्य के एक सरणी, सूचकांक-जोड़े में मूल्यों की सरणी को चालू करना और उस का अधिकतम / मिनट लेना होगा। यह सबसे बड़ा / सबसे छोटा सूचकांक देता है जिसमें अधिकतम / मिनट होता है (यानी जोड़े पहले तत्व की तुलना करके और फिर दूसरे तत्व की तुलना अगर पहले वाले समान हैं)। ध्यान दें कि यह वास्तव में सरणी बनाने के लिए आवश्यक नहीं है, क्योंकि मिनट / अधिकतम इनपुट के रूप में जनरेटर की अनुमति देते हैं।

values = [3,4,5]
(m,i) = max((v,i) for i,v in enumerate(values))
print (m,i) #(5, 2)

30
list=[1.1412, 4.3453, 5.8709, 0.1314]
list.index(min(list))

आपको न्यूनतम का पहला सूचकांक देगा।


18

मुझे लगता है कि सबसे अच्छी बात यह है कि इस सूची को सूची में परिवर्तित करें numpy arrayऔर इस फ़ंक्शन का उपयोग करें:

a = np.array(list)
idx = np.argmax(a)

14

मुझे भी इसमें दिलचस्पी थी और परफ्लोट (मेरा एक पालतू प्रोजेक्ट) का उपयोग करके सुझाए गए कुछ समाधानों की तुलना में ।

उस सुन्न के अरगिन को ,

numpy.argmin(x)

इनपुट से निहित रूपांतरण के साथ, बड़ी पर्याप्त सूचियों के लिए सबसे तेज़ तरीका listहै numpy.array

यहाँ छवि विवरण दर्ज करें


प्लॉट बनाने के लिए कोड:

import numpy
import operator
import perfplot


def min_enumerate(a):
    return min(enumerate(a), key=lambda x: x[1])[0]


def min_enumerate_itemgetter(a):
    min_index, min_value = min(enumerate(a), key=operator.itemgetter(1))
    return min_index


def getitem(a):
    return min(range(len(a)), key=a.__getitem__)


def np_argmin(a):
    return numpy.argmin(a)


perfplot.show(
    setup=lambda n: numpy.random.rand(n).tolist(),
    kernels=[
        min_enumerate,
        min_enumerate_itemgetter,
        getitem,
        np_argmin,
        ],
    n_range=[2**k for k in range(15)],
    logx=True,
    logy=True,
    )

ध्यान दें कि एक ही निष्कर्ष मेरे जवाब में पहले से ही 2 साल पहले से ऊपर पोस्ट किया गया है, जब और क्यों argmin इस्तेमाल किया जा सकता है या नहीं पर अधिक जानकारी के साथ। उस उत्तर को हटाने पर विचार करें, जो इस पृष्ठ पर पहले से प्रस्तावित प्रस्ताव को योग्यता नहीं दे रहा है। समान व्यवहार के लिए SO पर अपने अन्य उत्तरों की समीक्षा करने पर भी विचार करें: आप अपने प्रदर्शन विश्लेषण में सबसे अच्छा समाधान प्रदान करने वाले वास्तविक उत्तर का हवाला नहीं देते हैं। यह बल्कि बुरा है, विशेष रूप से> 10K प्रतिनिधि वाले किसी व्यक्ति के लिए जो बेहतर जानने के लिए काफी लंबे समय से है।
gg349

@ gg349, बहुत अच्छे अंक, लेकिन वह परिणामों को उत्पन्न करने के लिए स्रोत कोड प्रदान करता है, जिससे यह आसानी से प्रतिलिपि प्रस्तुत करने योग्य और अन्य समाधानों की तुलना करने के लिए अनुकूल है। मैं सहमत हूं कि वह इस उत्तर को एक डुप्लिकेट के रूप में हटाने पर विचार कर सकता है, लेकिन शायद आप अपने द्वारा उपयोग किए गए कोड को शामिल या लिंक करके अपने उत्तर में मूल्य जोड़ सकते हैं?
रकुराई


8

अधिकतम मान प्राप्त करने के बाद, यह आज़माएँ:

max_val = max(list)
index_max = list.index(max_val)

बहुत सारे विकल्पों की तुलना में बहुत सरल।


6

मुझे लगता है कि ऊपर दिए गए जवाब से आपकी समस्या हल हो जाती है, लेकिन मैंने सोचा कि मैं एक ऐसा तरीका साझा करूँगा जो आपको न्यूनतम प्रदान करे और सभी सूचकांक न्यूनतम प्रकट हों।

minval = min(mylist)
ind = [i for i, v in enumerate(mylist) if v == minval]

यह सूची को दो बार पास करता है लेकिन अभी भी काफी तेज है। यह न्यूनतम के पहले मुकाबले के सूचकांक को खोजने की तुलना में थोड़ा धीमा है। तो अगर आपको सिर्फ एक मिनीमा की आवश्यकता है, तो मैट एंडरसन के समाधान का उपयोग करें, यदि आपको उन सभी की आवश्यकता है, तो इसका उपयोग करें।


1
मुझे यह पसंद है क्योंकि यह बेस पायथन का उपयोग करता है, और मुझे आइटम की तुलना में समझने के लिए सूची समझ को आसान लगता है, (और इस तरह के कार्यों को हल करने के लिए पर्याप्त लचीला है, जैसे कि ....)
जेम्स

कच्चा। यह मेरे लिए ज़्यादा प्रधान है।
देव_मन डे

6

Numpy मॉड्यूल के फंक्शन numpy.where का उपयोग करें

import numpy as n
x = n.array((3,3,4,7,4,56,65,1))

न्यूनतम मूल्य के सूचकांक के लिए:

idx = n.where(x==x.min())[0]

अधिकतम मूल्य के सूचकांक के लिए:

idx = n.where(x==x.max())[0]

वास्तव में, यह फ़ंक्शन अधिक शक्तिशाली है। आप 3 और 60 के बीच मूल्य के सूचकांक के लिए सभी प्रकार के बूलियन ऑपरेशन कर सकते हैं:

idx = n.where((x>3)&(x<60))[0]
idx
array([2, 3, 4, 5])
x[idx]
array([ 4,  7,  4, 56])

अजगर में इंडेक्स 0. पर शुरू होता है। इंडेक्स लौटा 6 (65 के लिए) होगा, जबकि आपका कोड 7 (ओपी का प्रश्न "इंडेक्स प्राप्त करना ..." था)
टैगोमा

कमांड में, मैंने न्यूनतम मूल्य (यहां: 1) के सूचकांक के लिए क्वेर किया है जिसका सूचकांक आईएस 7. 65 सरणी में तत्वों का अधिकतम मूल्य है। यदि आप टाइप करते हैं: n.where (x == x.max ()) [0] आपको अधिकतम का इंडेक्स मिलेगा। मूल्य जो यहाँ 65 है। इसका सूचकांक 6 होगा
इशान तोमर

सुन्न का उपयोग: शायद इस आवेदन में निषिद्ध है। लेकिन अगर आप सुन्न का उपयोग करने जा रहे हैं, तो argmin()आपने यहां क्या किया, इसके बजाय सिर्फ उपयोग करना बेहतर है।
RBF06

धन्यवाद @ RBF06 मैं इसे देखूंगा।
इशान तोमर

5

यह बिल्ट-इन enumerate()और max()फ़ंक्शन और फ़ंक्शन के वैकल्पिक keyतर्क max()और एक साधारण लंबोदर अभिव्यक्ति का उपयोग करके बस संभव है :

theList = [1, 5, 10]
maxIndex, maxValue = max(enumerate(theList), key=lambda v: v[1])
# => (2, 10)

डॉक्स में इसके लिए max()कहा गया है कि keyतर्क फ़ंक्शन की तरह एक फ़ंक्शन की अपेक्षा list.sort()करता है। सॉर्टिंग हाउ टू भी देखें ।

यह उसी के लिए काम करता है min()। Btw यह पहला अधिकतम / मिनट मूल्य देता है।


देर से लेकिन सबसे अच्छा जवाब (यदि आपको गति की आवश्यकता नहीं है)।
एमएमज

5

कहो कि आपके पास एक सूची है जैसे:

a = [9,8,7]

निम्नलिखित दो विधियां न्यूनतम तत्व और इसके सूचकांक के साथ एक ट्यूपल प्राप्त करने के लिए बहुत कॉम्पैक्ट तरीके हैं। दोनों एक समान लेते हैं को प्रोसेस समय लगता है। मुझे जिप विधि पसंद है, लेकिन यह मेरा स्वाद है।

ज़िप विधि

element, index = min(list(zip(a, range(len(a)))))

min(list(zip(a, range(len(a)))))
(7, 2)

timeit min(list(zip(a, range(len(a)))))
1.36 µs ± 107 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

गणना करने की विधि

index, element = min(list(enumerate(a)), key=lambda x:x[1])

min(list(enumerate(a)), key=lambda x:x[1])
(2, 7)

timeit min(list(enumerate(a)), key=lambda x:x[1])
1.45 µs ± 78.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

4

जब तक आप जानते हैं कि लैम्ब्डा और "कुंजी" तर्क का उपयोग कैसे करें, एक सरल उपाय है:

max_index = max( range( len(my_list) ), key = lambda index : my_list[ index ] )

बहुत साफ! और स्वीकृत उत्तर के विपरीत, यह सही O (n) है, है ना? मुझे पता है कि ओ (2 एन) को ओ (एन) माना जाता है, लेकिन बहुत बड़े के लिए nयह काफी धीमा हो सकता है।
केवलर


3

पहले सूचकांक को जोड़ने और फिर उन्हें उलटने के लिए परेशान क्यों? Enumerate () फ़ंक्शन ज़िप () फ़ंक्शन उपयोग का सिर्फ एक विशेष मामला है। आइए इसे एपप्रोटेट तरीके से उपयोग करें:

my_indexed_list = zip(my_list, range(len(my_list)))

min_value, min_index = min(my_indexed_list)
max_value, max_index = max(my_indexed_list)

2

जो पहले ही कहा जा चुका है, बस एक मामूली जोड़। values.index(min(values))मिनट का सबसे छोटा सूचकांक वापस करने के लिए लगता है। निम्नलिखित को सबसे बड़ा सूचकांक मिलता है:

    values.reverse()
    (values.index(min(values)) + len(values) - 1) % len(values)
    values.reverse()

अंतिम पंक्ति को छोड़ा जा सकता है अगर जगह में उलटने का साइड इफेक्ट मायने नहीं रखता है।

सभी घटनाओं के माध्यम से पुनरावृति करने के लिए

    indices = []
    i = -1
    for _ in range(values.count(min(values))):
      i = values[i + 1:].index(min(values)) + i + 1
      indices.append(i)

संक्षिप्तता के खातिर। min(values), values.count(min)लूप के बाहर कैश करना शायद एक बेहतर विचार है ।


2
reversed(…)इसके बजाय ….reverse()बेहतर होने की संभावना है क्योंकि यह किसी भी तरह से एक जनरेटर को म्यूट नहीं करता है और वापस नहीं करता है। और सभी घटनाएं भी हो सकती हैंminv = min(values); indices = [i for i, v in enumerate(values) if v == minv]
होवरहेल

2

यदि आप अतिरिक्त मॉड्यूल आयात नहीं करना चाहते हैं, तो सूची में न्यूनतम मूल्य के साथ अनुक्रमणिका खोजने का एक सरल तरीका है:

min_value = min(values)
indexes_with_min_value = [i for i in range(0,len(values)) if values[i] == min_value]

तो पहले एक उदाहरण के लिए चुनें:

choosen = indexes_with_min_value[0]

1

मौजूदा उत्तर पर टिप्पणी करने के लिए पर्याप्त उच्च प्रतिनिधि नहीं है।

लेकिन https://stackoverflow.com/a/11825864/3920439 उत्तर के लिए

यह पूर्णांक के लिए काम करता है, लेकिन फ्लोट की सरणी के लिए काम नहीं करता है (कम से कम अजगर 3.6 में) यह उठाएंगे TypeError: list indices must be integers or slices, not float


0

https://docs.python.org/3/library/functions.html#max

यदि कई आइटम अधिकतम हैं, तो फ़ंक्शन पहले वाले का सामना करता है। यह अन्य सॉर्ट-स्टेबिलिटी प्रोटेक्शन टूल जैसे कि के अनुरूप हैsorted(iterable, key=keyfunc, reverse=True)[0]

पहले से अधिक प्राप्त करने के लिए सॉर्ट विधि का उपयोग करें।

import operator

x = [2, 5, 7, 4, 8, 2, 6, 1, 7, 1, 8, 3, 4, 9, 3, 6, 5, 0, 9, 0]

min = False
max = True

min_val_index = sorted( list(zip(x, range(len(x)))), key = operator.itemgetter(0), reverse = min )

max_val_index = sorted( list(zip(x, range(len(x)))), key = operator.itemgetter(0), reverse = max )


min_val_index[0]
>(0, 17)

max_val_index[0]
>(9, 13)

import ittertools

max_val = max_val_index[0][0]

maxes = [n for n in itertools.takewhile(lambda x: x[0] == max_val, max_val_index)]

0

इस बारे में क्या:

a=[1,55,2,36,35,34,98,0]
max_index=dict(zip(a,range(len(a))))[max(a)]

यह aकुंजी के रूप में आइटम से एक शब्दकोश बनाता है और मूल्यों के रूप में उनकी अनुक्रमित करता है, इस प्रकार dict(zip(a,range(len(a))))[max(a)]वह मान लौटाता है max(a)जो कुंजी से मेल खाता है जो अधिकतम में सूचकांक है। मैं अजगर में एक शुरुआत कर रहा हूँ तो मैं इस समाधान की कम्प्यूटेशनल जटिलता के बारे में पता नहीं है।

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