web-dev-qa-db-fra.com

Comment trouver toutes les positions de la valeur maximale dans une liste?

J'ai une liste:

a = [32, 37, 28, 30, 37, 25, 27, 24, 35, 55, 23, 31, 55, 21, 40, 18, 50,
             35, 41, 49, 37, 19, 40, 41, 31]

l'élément max est de 55 (deux éléments en position 9 et 12)

Je dois trouver sur quelle (s) position (s) la valeur maximale est située. S'il vous plaît, aidez.

110
Bob
>>> m = max(a)
>>> [i for i, j in enumerate(a) if j == m]
[9, 12]
167
SilentGhost
a.index(max(a))

vous indiquera l’index de la première instance du plus grand élément valorisé de la liste a.

239
nmichaels

La réponse choisie (et la plupart des autres) nécessite au moins deux passages dans la liste.
Voici une solution en un seul passage qui pourrait constituer un meilleur choix pour les listes plus longues. 

Édité: Pour remédier aux deux lacunes signalées par @John Machin. Pour (2), j’ai tenté d’optimiser les tests en fonction de la probabilité d’apparition estimée de chaque condition et des inférences autorisées par les prédécesseurs. C'était un peu délicat de déterminer les valeurs d'initialisation correctes pour max_val et max_indices, ce qui a fonctionné dans tous les cas possibles, en particulier si max était la première valeur de la liste - mais je crois que c'est le cas maintenant.

def maxelements(seq):
    ''' Return list of position(s) of largest element '''
    max_indices = []
    if seq:
        max_val = seq[0]
        for i,val in ((i,val) for i,val in enumerate(seq) if val >= max_val):
            if val == max_val:
                max_indices.append(i)
            else:
                max_val = val
                max_indices = [i]

    return max_indices
18
martineau

Je ne peux pas reproduire la performance inégalée de @ SilentGhost citée par @martineau. Voici mon effort avec des comparaisons:

=== maxelements.py ===

a = [32, 37, 28, 30, 37, 25, 27, 24, 35, 55, 23, 31, 55, 21, 40, 18, 50,
             35, 41, 49, 37, 19, 40, 41, 31]
b = range(10000)
c = range(10000 - 1, -1, -1)
d = b + c

def maxelements_s(seq): # @SilentGhost
    ''' Return list of position(s) of largest element '''
    m = max(seq)
    return [i for i, j in enumerate(seq) if j == m]

def maxelements_m(seq): # @martineau
    ''' Return list of position(s) of largest element '''
    max_indices = []
    if len(seq):
        max_val = seq[0]
        for i, val in ((i, val) for i, val in enumerate(seq) if val >= max_val):
            if val == max_val:
                max_indices.append(i)
            else:
                max_val = val
                max_indices = [i]
    return max_indices

def maxelements_j(seq): # @John Machin
    ''' Return list of position(s) of largest element '''
    if not seq: return []
    max_val = seq[0] if seq[0] >= seq[-1] else seq[-1]
    max_indices = []
    for i, val in enumerate(seq):
        if val < max_val: continue
        if val == max_val:
            max_indices.append(i)
        else:
            max_val = val
            max_indices = [i]
    return max_indices

Résultats d'un vieil ordinateur portable épaté sous Python 2.7 sous Windows XP SP3:

>\python27\python -mtimeit -s"import maxelements as me" "me.maxelements_s(me.a)"
100000 loops, best of 3: 6.88 usec per loop

>\python27\python -mtimeit -s"import maxelements as me" "me.maxelements_m(me.a)"
100000 loops, best of 3: 11.1 usec per loop

>\python27\python -mtimeit -s"import maxelements as me" "me.maxelements_j(me.a)"
100000 loops, best of 3: 8.51 usec per loop

>\python27\python -mtimeit -s"import maxelements as me;a100=me.a*100" "me.maxelements_s(a100)"
1000 loops, best of 3: 535 usec per loop

>\python27\python -mtimeit -s"import maxelements as me;a100=me.a*100" "me.maxelements_m(a100)"
1000 loops, best of 3: 558 usec per loop

>\python27\python -mtimeit -s"import maxelements as me;a100=me.a*100" "me.maxelements_j(a100)"
1000 loops, best of 3: 489 usec per loop
8
John Machin
a = [32, 37, 28, 30, 37, 25, 27, 24, 35, 
         55, 23, 31, 55, 21, 40, 18, 50,
         35, 41, 49, 37, 19, 40, 41, 31]

import pandas as pd

pd.Series(a).idxmax()

9

C'est comme ça que je le fais d'habitude.

5
Arijit Laha

Vous pouvez également utiliser le paquet numpy:

import numpy as np
A = np.array(a)
maximum_indices = np.where(A==max(a))

Cela retournera un tableau numpy de tous les index contenant la valeur max.

si vous voulez transformer ceci en une liste:

maximum_indices_list = maximum_indices.tolist()
4
user3569257
>>> max(enumerate([1,2,3,32,1,5,7,9]),key=lambda x: x[1])
>>> (3, 32)
4
Hari Roshan

@shash a répondu ailleurs

Une façon pythonique de trouver l’index de l’élément maximum de la liste serait 

position = max(enumerate(a), key=lambda x: x[1])[0]

Lequel on passe. Pourtant, il est plus lent que la solution de @Silent_Ghost et, plus encore, de @nmichaels:

for i in s m j n; do echo $i;  python -mtimeit -s"import maxelements as me" "me.maxelements_${i}(me.a)"; done
s
100000 loops, best of 3: 3.13 usec per loop
m
100000 loops, best of 3: 4.99 usec per loop
j
100000 loops, best of 3: 3.71 usec per loop
n
1000000 loops, best of 3: 1.31 usec per loop
2
serv-inc

Voici la valeur maximale et les index sur lesquels elle apparaît:

>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> a = [32, 37, 28, 30, 37, 25, 27, 24, 35, 55, 23, 31, 55, 21, 40, 18, 50, 35, 41, 49, 37, 19, 40, 41, 31]
>>> for i, x in enumerate(a):
...     d[x].append(i)
... 
>>> k = max(d.keys())
>>> print k, d[k]
55 [9, 12]

Plus tard: pour la satisfaction de @SilentGhost

>>> from itertools import takewhile
>>> import heapq
>>> 
>>> def popper(heap):
...     while heap:
...         yield heapq.heappop(heap)
... 
>>> a = [32, 37, 28, 30, 37, 25, 27, 24, 35, 55, 23, 31, 55, 21, 40, 18, 50, 35, 41, 49, 37, 19, 40, 41, 31]
>>> h = [(-x, i) for i, x in enumerate(a)]
>>> heapq.heapify(h)
>>> 
>>> largest = heapq.heappop(h)
>>> indexes = [largest[1]] + [x[1] for x in takewhile(lambda large: large[0] == largest[0], popper(h))]
>>> print -largest[0], indexes
55 [9, 12]
2
hughdbrown

Idée similaire avec une compréhension de liste mais sans énumérer

m = max(a)
[i for i in range(len(a)) if a[i] == m]
2
Salvador Dali

Juste une ligne:

idx = max(range(len(a)), key = lambda i: a[i])
2
divkakwani

Vous pouvez le faire de différentes manières.

L'ancienne manière conventionnelle est,

maxIndexList = list() #this list will store indices of maximum values
maximumValue = max(a) #get maximum value of the list
length = len(a)       #calculate length of the array

for i in range(length): #loop through 0 to length-1 (because, 0 based indexing)
    if a[i]==maximumValue: #if any value of list a is equal to maximum value then store its index to maxIndexList
        maxIndexList.append(i)

print(maxIndexList) #finally print the list

Une autre façon sans calculer la longueur de la liste et stocker la valeur maximale dans une variable,

maxIndexList = list()
index = 0 #variable to store index
for i in a: #iterate through the list (actually iterating through the value of list, not index )
    if i==max(a): #max(a) returns a maximum value of list.
        maxIndexList.append(index) #store the index of maximum value
index = index+1 #increment the index

print(maxIndexList)

Nous pouvons le faire de façon intelligente et pythonique! Utilisation de la compréhension de liste sur une seule ligne,

maxIndexList = [i for i,j in enumerate(a) if j==max(a)] #here,i=index and j = value of that index

Tous mes codes sont en Python 3.

0
Taohidul Islam
import operator

def max_positions(iterable, key=None, reverse=False):
  if key is None:
    def key(x):
      return x
  if reverse:
    better = operator.lt
  else:
    better = operator.gt

  it = enumerate(iterable)
  for pos, item in it:
    break
  else:
    raise ValueError("max_positions: empty iterable")
    # note this is the same exception type raised by max([])
  cur_max = key(item)
  cur_pos = [pos]

  for pos, item in it:
    k = key(item)
    if better(k, cur_max):
      cur_max = k
      cur_pos = [pos]
    Elif k == cur_max:
      cur_pos.append(pos)

  return cur_max, cur_pos

def min_positions(iterable, key=None, reverse=False):
  return max_positions(iterable, key, not reverse)

>>> L = range(10) * 2
>>> L
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> max_positions(L)
(9, [9, 19])
>>> min_positions(L)
(0, [0, 10])
>>> max_positions(L, key=lambda x: x // 2, reverse=True)
(0, [0, 1, 10, 11])
0
Roger Pate

Ce code n’est pas aussi sophistiqué que les réponses précédentes, mais il fonctionnera:

m = max(a)
n = 0    # frequency of max (a)
for number in a :
    if number == m :
        n = n + 1
ilist = [None] * n  # a list containing index values of maximum number in list a.
ilistindex = 0
aindex = 0  # required index value.    
for number in a :
    if number == m :
        ilist[ilistindex] = aindex
        ilistindex = ilistindex + 1
    aindex = aindex + 1

print ilist

ilist dans le code ci-dessus contiendrait toutes les positions du nombre maximum dans la liste.

0
Sukrit Gupta

Si vous souhaitez obtenir les indices des plus grands nombres n dans une liste appelée data, vous pouvez utiliser des pandas sort_values :

pd.Series(data).sort_values(ascending=False).index[0:n]
0
dannyg