622

ミニマックスアルゴリズムのリストでPythonmaxと関数を使用していますが、またはによって返される値のインデックスが必要です。言い換えれば、どの動きが最大(最初のプレーヤーのターン)または最小(2番目のプレーヤー)の値を生み出したかを知る必要があります。minmax()min()

for i in range(9):
    new_board = current_board.new_board_with_move([i / 3, i % 3], player)

    if new_board:
        temp = min_max(new_board, depth + 1, not is_min_level)  
        values.append(temp)

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

値だけでなく、最小値または最大値の実際のインデックスを返すことができる必要があります。

4

24 に答える 24

604

listvalues = [3,6,1,5]があり、最小の要素のインデックスが必要だとします。つまりindex_min = 2、この場合です。

itemgetter()他の回答に示されている解決策を避け、代わりに使用してください

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

を使用する必要もなく、 を使用する必要import operatorもなく、 を使用enumerateしたソリューションよりも常に高速 (以下のベンチマーク) であるためitemgetter()です。

numpynumpy 配列を扱っている場合、または依存関係として余裕がある場合は、使用することも検討してください

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

次の場合、純粋な Python リストに適用したとしても、これは最初のソリューションよりも高速です。

  • いくつかの要素よりも大きい (私のマシンでは約 2**4 要素)
  • numpy純粋なリストから配列へのメモリコピーを実行できます

このベンチマークが指摘しているように: ここに画像の説明を入力

itemgetter()上記の2つのソリューション(青:純粋なpython、最初のソリューション)(赤、numpyソリューション)と(黒、参照ソリューション)に基づく標準ソリューションについて、python 2.7を使用してマシンでベンチマークを実行しました。Python 3.5 と同じベンチマークでは、メソッドが上記の Python 2.7 の場合とまったく同じであることが示されました。

于 2012-08-06T09:43:48.660 に答える
552
if is_min_level:
    return values.index(min(values))
else:
    return values.index(max(values))
于 2010-03-18T23:23:08.070 に答える
360

リスト内の項目を列挙すると、最小/最大インデックスと値を同時に見つけることができますが、リストの元の値に対して最小/最大を実行します。そのようです:

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

このようにして、リストは最小 (または最大) に対して 1 回だけトラバースされます。

于 2010-03-19T00:18:32.087 に答える
132

数値のリスト内で max のインデックスを見つけたい場合 (これはあなたのケースのようです)、numpy を使用することをお勧めします。

import numpy as np
ind = np.argmax(mylist)
于 2012-11-23T17:41:42.973 に答える
45

おそらく、より簡単な解決策は、値の配列を値の配列、インデックスペアに変換し、その最大/最小を取ることです。これにより、最大/最小を持つ最大/最小のインデックスが得られます (つまり、最初の要素を最初に比較し、最初の要素が同じ場合は 2 番目の要素を比較することによって、ペアを比較します)。min/max はジェネレーターを入力として許可するため、実際に配列を作成する必要はないことに注意してください。

values = [3,4,5]
(m,i) = max((v,i) for i,v in enumerate(values))
print (m,i) #(5, 2)
于 2012-12-21T11:53:50.750 に答える
33
seq=[1.1412, 4.3453, 5.8709, 0.1314]
seq.index(min(seq))

最小の最初のインデックスを提供します。

于 2013-09-07T21:30:44.487 に答える
10

上記の答えはあなたの問題を解決すると思いますが、最小値と最小値が表示されるすべてのインデックスを提供する方法を共有したいと思いました。

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

これはリストを2回通過しますが、それでもかなり高速です。ただし、最小値の最初の遭遇のインデックスを見つけるよりもわずかに遅くなります。したがって、最小値の1つだけが必要な場合は、Matt Andersonのソリューションを使用し、すべてが必要な場合は、これを使用します。

于 2011-04-14T18:22:41.383 に答える
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])
于 2015-04-16T08:29:14.170 に答える
5

次のようなリストがあるとします。

a = [9,8,7]

次の 2 つのメソッドは、最小要素とそのインデックスを含むタプルを取得する非常にコンパクトな方法です。どちらも処理に同じくらいの時間がかかります。私はzip方式の方が好きですが、それが私の好みです。

ジップ方式

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)
于 2018-02-26T10:29:40.217 に答える
4

最初にインデックスを追加してから逆にする必要があるのはなぜですか? Enumerate() 関数は、zip() 関数の使用法の特殊なケースです。適切な方法で使用しましょう。

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)
于 2015-03-17T13:45:16.197 に答える
2

すでに述べたことへのほんの少しの追加です。 values.index(min(values))min の最小のインデックスを返すようです。以下は、最大のインデックスを取得します。

    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)おそらく、ループの外でキャッシュする方がよいでしょう。

于 2012-04-06T16:09:02.853 に答える
1

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

複数の項目が最大の場合、関数は最初に検出された項目を返します。これは、次のような他のソート安定性維持ツールと一致しています。sorted(iterable, key=keyfunc, reverse=True)[0]

最初に遭遇したもの以上のものを取得するには、sort メソッドを使用します。

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)]
于 2015-09-17T20:42:25.040 に答える
0

これはどうですか:

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

aの項目をキーとして、そのインデックスを値として辞書を作成し、a の最大値のインデックスであるdict(zip(a,range(len(a))))[max(a)]キーに対応する値を返します。max(a)私はPythonの初心者なので、このソリューションの計算の複雑さについては知りません。

于 2019-10-12T09:10:33.667 に答える