একটি তালিকায় সর্বাধিক () / মিনিট () ব্যবহার করে প্রদত্ত সর্বোচ্চ বা মিনিট আইটেমের সূচক পাওয়া


464

আমি পাইথন এর ব্যবহার করছি maxএবং minফাংশন তালিকা একটি minimax অ্যালগরিদম জন্য, এবং আমি মূল্যের সূচক দ্বারা ফিরে প্রয়োজন 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
অনেক কিছু divmodবলতে আটকাতে বিল্টিনটি বিদ্যমান [i / 3, i % 3]
মাইক গ্রাহাম

উত্তর:


416
যদি হয় মিনিভেল:
    রিটার্ন মানসমূহ। সূচি (মিনিট (মান))
অন্য:
    রিটার্ন ভ্যালু.ইন্ডেক্স (সর্বাধিক (মান))

38
@ কেভিন গ্রিফিন, নোট করুন যে এটি আপনাকে সর্বনিম্ন / সর্বাধিক সর্বাধিক কয়েকটি ঘটনার মধ্যে একটি মাত্র পেয়েছে। এটি আপনি যা চান তা হতে পারে না, উদাহরণস্বরূপ যদি আপনার উপার্জন একই দুটি উপায়ে বাড়ানো সম্ভব হয় তবে তাদের মধ্যে একটির ফলে অন্য খেলোয়াড়কে আরও বেশি কষ্ট দেয়। আমি জানি না এটি আপনার কে বিবেচনা করা দরকার কিনা।
মাইক গ্রাহাম

89
@ কাশ্যপ এটি আসলে ও (এন), ও নয় (এন ^ 2)। মিনিটের ক্ষেত্রে, প্রথম মিনিটের (মানগুলি) মূল্যায়ন করা হয়, যা ও (এন) হয়, তারপরে ভ্যালু.ইনডেক্স () বলা হয়, এটি ও (এন )ও হয়। ও (এন) + ও (এন) = ও (এন)। সূচকের যুক্তিটি একবারে মূল্যায়ন করা হয়। এটি এর সমতুল্য:tmp = min(values); return values.index(tmp)
টম কার্জেস

@ খুব বেশি পিএইচপি করুন যখন উপাদানগুলির পুনরাবৃত্তি ঘটে তখন কী করবেন?
শশী টুঙ্গা

@ শশীতুঙ্গা [তালিকা]। সূচিপত্র () কেবল কোনও কিছুর প্রথম উপস্থিতি ফিরে আসে, এটি গ্যারান্টিযুক্ত নয় যে এটি একচেটিয়া, ন্যূনতম মান তালিকার মধ্যে অনন্য হতে পারে না
স্কট অ্যান্ডারসন

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)

আপনি যদি খাঁটি পাইথন তালিকায় এটি প্রয়োগ করেন তবে এটি প্রথম সমাধানের চেয়ে দ্রুততর হবে যদি:

  • এটি কয়েকটি উপাদানগুলির চেয়ে বড় (আমার মেশিনে প্রায় 2 ** 4 টি উপাদান)
  • আপনি খাঁটি তালিকা থেকে একটি numpyঅ্যারেতে মেমরির অনুলিপি বহন করতে পারেন

এই মানদণ্ডটি যেমন উল্লেখ করেছে: এখানে চিত্র বর্ণনা লিখুন

উপরোক্ত দুটি সমাধান (নীল: খাঁটি পাইথন, প্রথম দ্রবণ) (লাল, আঙ্গুল সমাধান) এবং itemgetter()(কালো, রেফারেন্স সমাধান) ভিত্তিক মানক সমাধানের জন্য আমি আমার মেশিনে পাইথন ২.7 দিয়ে বেঞ্চমার্ক চালিয়েছি । পাইথন ৩.৫ সহ একই মানদণ্ডটি দেখিয়েছিল যে পদ্ধতিগুলি উপস্থাপিত পাইথন ২. case ক্ষেত্রে ঠিক একইরকম তুলনা করে


খুব শক্তিশালী +1। আমি প্রস্তাবিত সমাধানগুলি এবং আপনার সংক্ষিপ্তসারগুলির থাম্বের বিধিগুলির বেঞ্চমার্কিং পছন্দ করি। আমি নীচে অন্য উত্তরে পরামর্শ হিসাবে, আপনি কি অন্যদের আপনার ফলাফল পুনরুত্পাদন করতে পারে তাই আপনার পরীক্ষা কোড সরবরাহ (বা লিঙ্ক) করতে পারেন? সময়ের সাথে সাথে মেশিন এবং লাইব্রেরিগুলি পরিবর্তিত হয় এবং এটি অন্যান্য সমাধানগুলির সাথে তুলনা করার অনুমতি দেয়।
রাকুরই

3
আমি মনে করি একটি টাইপো থাকতে পারে: এক্সরেঞ্জ। এটি কি সীমা হওয়া উচিত নয়?
লিন্ডসে ফোলার

6
@ লিন্ডসেফলার xrange()এখন অবনতি হয়েছে, আপনি ব্যবহার করতে পারেনrange()
ডেভিড

np.argmin ভাসমানদের জন্য কাজ করে না। কেবলমাত্র প্রথম পরামর্শটি কালি এবং ফ্লোটে কাজ করে।
জিমাহ

আমার মনে হয় আপনি ভুল হয়ে গেছেন, চেষ্টা করুন import numpy as np; x = [2.3, -1.4]; np.argmin(x)। আপনি দেখতে পাবেন যে argmin
ভাসমানগুলিতেও

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)


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 বছরেরও বেশি আগে পোস্ট করা হয়েছে, কখন এবং কেন আরগমিন ব্যবহার করা যায় বা না সে সম্পর্কে আরও তথ্যের সাথে। উত্তর মুছে ফেলার কথা বিবেচনা করুন, যা এই একই পৃষ্ঠায় ইতিমধ্যে প্রস্তাবিত বিষয়গুলিরও যোগ্যতা দিচ্ছে না। অনুরূপ আচরণের জন্য এসও তে আপনার অন্যান্য উত্তরগুলি পর্যালোচনা করার বিষয়টিও বিবেচনা করুন: আপনি আপনার পারফরম্যান্স বিশ্লেষণে সেরা সমাধান সরবরাহ করে এমন আসল উত্তরটি উদ্ধৃত করবেন না বলে মনে হয়। এটি বরং খারাপ, বিশেষত> 10 কে প্রতিনিধিত্বকারী কারওর জন্য যা আরও ভালভাবে জানতে যথেষ্ট দীর্ঘ হয়েছে।
gg349

@ gg349, খুব ভাল পয়েন্ট, তবে তিনি ফলাফল উত্পন্ন করার জন্য সোর্স কোড সরবরাহ করেন, এটি সহজেই পুনরুত্পাদনযোগ্য এবং অন্যান্য সমাধানের সাথে তুলনার সাথে খাপ খাইয়ে নিতে সক্ষম করে। আমি সম্মত হই যে তিনি এই উত্তরটিকে সদৃশ হিসাবে সরিয়ে নেওয়ার কথা বিবেচনা করতে পারেন তবে আপনি যে কোডটি ব্যবহার করেছেন তা যুক্ত করে বা লিঙ্ক করে আপনি নিজের উত্তরটির মান যুক্ত করতে পারেন?
রকুরই

8

একটি নমপি অ্যারে এবং আরগম্যাক্স () ফাংশন ব্যবহার করুন

 a=np.array([1,2,3])
 b=np.argmax(a)
 print(b) #2

8

আপনি সর্বোচ্চ মানগুলি পাওয়ার পরে এটি ব্যবহার করে দেখুন:

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

বিকল্পগুলির অনেকের চেয়ে অনেক সহজ।


6

আমি মনে করি উপরের উত্তরটি আপনার সমস্যার সমাধান করে তবে আমি ভেবেছিলাম যে আমি এমন একটি পদ্ধতি ভাগ করব যা আপনাকে সর্বনিম্ন এবং সমস্ত সূচককে সর্বনিম্ন দেয় gives

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

এটি তালিকাটি দুইবার পাস করেছে তবে এখনও বেশ দ্রুত। এটি সর্বনিম্ন প্রথম মুখোমুখি হওয়ার সূচকটি খুঁজে পাওয়ার চেয়ে কিছুটা ধীর। সুতরাং আপনার যদি কেবল একটি মিনিমা প্রয়োজন হয়, ম্যাট অ্যান্ডারসনের সমাধানটি ব্যবহার করুন, যদি আপনার সকলের প্রয়োজন হয় তবে এটি ব্যবহার করুন।


1
আমি এটি পছন্দ করি কারণ এটি বেস পাইথন ব্যবহার করে, এবং আমি আইটেমজিটার, ল্যাম্বডা ইত্যাদির চেয়ে তালিকা বোঝা সহজতর বুঝতে পারি (এবং এটি বিভিন্ন ধরণের কাজগুলি সমাধান করার জন্য যথেষ্ট নমনীয় ....)
জেমস

কাঁচা। আমি এই পছন্দ।
দেব_মান

6

নম্পি মডিউলের ফাংশন 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])

অজগর সূচকটি ০. থেকে শুরু হয় সূচকটি ফিরে আসবে 6 (
for৫ এর

কমান্ডটিতে, আমি সর্বনিম্ন মানের সূচকটি অনুসন্ধান করেছি (এখানে: 1) যার সূচকটি হ'ল 65. 65 হ'ল অ্যারের উপাদানগুলির সর্বাধিক মান। আপনি যদি টাইপ করেন: n. কোথাও (x == x.max ()) [0] আপনি সর্বোচ্চের সূচক পাবেন। মান এখানে 65। এর সূচকটি 6 থেকে বেরিয়ে আসবে
hanশান তোমার

নম্পির ব্যবহার: সম্ভবত এই অ্যাপ্লিকেশনটিতে নিষিদ্ধ। তবে আপনি যদি অদ্ভুত ব্যবহার করতে চলেছেন তবে আপনি argmin()এখানে যা করেছেন তার পরিবর্তে আপনি তার ব্যবহারের চেয়ে আরও ভাল ।
RBF06

ধন্যবাদ @ আরবিএফ06 আমি এটি পরীক্ষা করে দেখব।
ইশান তোমার

5

বিল্ট-ইন enumerate()এবং max()ফাংশন এবং ফাংশনের alচ্ছিক keyযুক্তি max()এবং একটি সহজ ল্যাম্বডা এক্সপ্রেশন ব্যবহার করে এটি সহজেই সম্ভব :

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

এর জন্য দস্তাবেজগুলিতে max()বলা হয়েছে যে keyআর্গুমেন্টটি ফাংশনের মতো কোনও ফাংশন প্রত্যাশা list.sort()করে। কিভাবে বাছাই করা দেখুন

এটি একই জন্য কাজ করে min()। বিটিডব্লিউ এটি প্রথম সর্বোচ্চ / মিনিটের মান প্রদান করে returns


দেরীতে তবে সেরা উত্তর (যদি আপনার গতির প্রয়োজন না হয়)।
মিমজে

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 ] )

খুব পরিষ্কার! এবং গৃহীত উত্তরের মতো নয়, এটি সত্য ও (এন), ঠিক? আমি জানি যে ও (2 এন) কে ও (এন) হিসাবে বিবেচনা করা হয় তবে খুব বড় ক্ষেত্রে nএটি লক্ষণীয়ভাবে ধীর হতে পারে।
কেভলার


3

প্রথমে সূচকগুলি যুক্ত করতে এবং তারপরে বিপরীত কেন বিরক্ত করবেন? গণনা () ফাংশনটি জিপ () ফাংশন ব্যবহারের কেবল একটি বিশেষ ক্ষেত্রে। আসুন এটি অ্যাপ্রোপিট পদ্ধতিতে ব্যবহার করুন:

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 এর উত্তরের জন্য

এটি পূর্ণসংখ্যার জন্য কাজ করে, তবে ফ্লোটগুলির অ্যারের জন্য কাজ করে না (কমপক্ষে পাইথন ৩.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)যা a এর সর্বাধিকের সূচক। আমি পাইথনের একটি শিক্ষানবিস তাই এই সমাধানের গণনার জটিলতা সম্পর্কে আমি জানি না।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.