Programming

목록에서 max () / min ()을 사용하여 반환 된 최대 또는 최소 항목의 인덱스 가져 오기

procodes 2020. 2. 26. 22:46
반응형

목록에서 max () / min ()을 사용하여 반환 된 최대 또는 최소 항목의 인덱스 가져 오기


minimax 알고리즘의 목록에서 Python maxmin함수를 사용 하고 있으며 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)

값뿐만 아니라 최소 또는 최대 값의 실제 색인을 반환 할 수 있어야합니다.


isMinLevel 인 경우 :
    반환 값. 인덱스 (분 (값))
그밖에:
    반환 값. 인덱스 (최대 (값))

list values = [3,6,1,5]가 있고 가장 작은 요소의 인덱스가 필요하다고 가정하십시오 ( index_min = 2이 경우).

itemgetter()다른 답변에 제시된 해결책을 피하고 대신 사용하십시오.

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

import operator를 사용할 필요 도없고 사용할 필요가 없으며를 사용 enumerate하는 솔루션보다 항상 빠릅니다 (아래 벤치 마크) itemgetter().

numpy 배열을 다루거나 numpy종속성으로 감당할 수있는 경우

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

다음과 같은 경우 순수 Python 목록에 적용하더라도 첫 번째 솔루션보다 빠릅니다.

  • 그것은 몇 가지 요소보다 큽니다 (내 컴퓨터의 약 2 ** 4 요소)
  • 순수한 목록에서 numpy배열로 메모리 사본을 감당할 수 있습니다

이 벤치 마크가 지적한대로 : 여기에 이미지 설명을 입력하십시오

위의 두 가지 솔루션 (파란색 : 순수한 파이썬, 첫 번째 솔루션) (빨간색, numpy 솔루션) 및 표준 솔루션 itemgetter()(검은 색, 참조 솔루션)에 대해 python 2.7을 사용하여 컴퓨터에서 벤치 마크를 실행했습니다 . python 3.5와 동일한 벤치 마크는 방법이 위에서 제시 한 python 2.7 사례와 정확히 동일하다는 것을 보여주었습니다.


목록의 항목을 열거하지만 목록의 원래 값에 대해 최소 / 최대를 수행하면 최소 / 최대 색인과 값을 동시에 찾을 수 있습니다. 이렇게 :

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

이런 식으로 목록은 최소 (또는 최대) 동안 한 번만 순회됩니다.


숫자 목록 (최대한 경우)에서 max의 색인을 찾으려면 numpy를 사용하는 것이 좋습니다.

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

아마도 더 간단한 해결책은 값 배열을 값 배열, 인덱스 쌍으로 바꾸고 그 최대 / 최소값을 취하는 것입니다. 이것은 최대 / 최소를 갖는 최대 / 최소 인덱스를 제공합니다 (즉, 첫 번째 요소를 먼저 비교 한 다음 첫 번째 요소가 동일한 경우 두 번째 요소를 비교하여 쌍을 비교합니다). min / max는 생성기를 입력으로 허용하므로 실제로 배열을 만들 필요는 없습니다.

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

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

최소의 첫 번째 색인을 제공합니다.


나는 이것에 관심이 있었고 perfplot (내 애완 동물 프로젝트)을 사용하여 제안 된 솔루션 중 일부를 비교했습니다 .

numpy의 argmin을 밝혀냅니다 .

numpy.argmin(x)

입력 list에서 a 로의 암시 적 변환에도 불구하고 충분히 큰 목록에 가장 빠른 방법입니다 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,
    )

numpy 배열과 argmax () 함수를 사용하십시오.

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

최대 값을 얻은 후 다음을 시도하십시오.

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

많은 옵션보다 훨씬 간단합니다.


가장 좋은 방법은 목록을 a로 변환 numpy array하고이 기능을 사용하는 것입니다.

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

위의 답변이 문제를 해결한다고 생각하지만 최소값과 최소값이 표시되는 방법을 공유한다고 생각했습니다.

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

이것은 목록을 두 번 통과하지만 여전히 매우 빠릅니다. 그러나 최소값의 첫 번째 색인을 찾는 것보다 약간 느립니다. 따라서 최소값 중 하나만 필요하면 Matt Anderson 의 솔루션을 사용하십시오. 모두 필요한 경우 이것을 사용하십시오.


numpy 모듈의 함수 numpy를 사용하십시오.

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

이것은 사용하여 간단하게 할 수있는 내장 enumerate()max()기능과 옵션 key의 인수 max()기능과 간단한 람다 식 :

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

문서에서는 인수가 함수와 같은 함수를 기대 max()한다고 말합니다 . 정렬 방법 도 참조하십시오 .keylist.sort()

그것은 동일하게 작동합니다 min(). Btw는 첫 번째 최대 / 최소 값을 반환합니다.


lambda와 "key"인수를 사용하는 방법을 알고 있다면 간단한 해결책은 다음과 같습니다.

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

다음과 같은 목록이 있다고 가정하십시오.

a = [9,8,7]

다음 두 가지 방법은 최소 요소와 해당 인덱스로 튜플을 얻는 매우 간단한 방법입니다. 둘 다 처리하는 데 비슷한 시간이 걸립니다 . 나는 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)

인덱스를 먼저 추가 한 다음 반대로 바꾸는 이유는 무엇입니까? 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)

이미 말한 것에 약간의 추가. 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)루프 외부 에 캐시하는 것이 좋습니다 .


추가 모듈을 가져 오지 않으려는 경우 목록에서 최소한의 값으로 인덱스를 찾는 간단한 방법 :

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]

간단합니다 :

stuff = [2, 4, 8, 15, 11]

index = stuff.index(max(stuff))

기존 답변에 대해 언급 할만한 담당자가 충분하지 않습니다.

그러나 https://stackoverflow.com/a/11825864/3920439 답변

이것은 정수에서는 작동하지만 부동 소수점 배열에서는 작동하지 않습니다 (적어도 Python 3.6에서는) TypeError: list indices must be integers or slices, not float


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

참고 : https://stackoverflow.com/questions/2474015/getting-the-index-of-the-returned-max-or-min-item-using-max-min-on-a-list



반응형