Respuestas:
>>> m = max(a)
>>> [i for i, j in enumerate(a) if j == m]
[9, 12]
a.index(max(a))
le indicará el índice de la primera instancia del elemento más valioso de la lista a
.
La respuesta elegida (y la mayoría de las otras) requieren al menos dos pasadas por la lista.
Aquí hay una solución de un solo paso que podría ser una mejor opción para listas más largas.
Editado: para abordar las dos deficiencias señaladas por @John Machin. Para (2) intenté optimizar las pruebas basadas en la probabilidad estimada de ocurrencia de cada condición y las inferencias permitidas por los predecesores. Fue un poco complicado descubrir los valores de inicialización adecuados para max_val
y max_indices
que funcionó para todos los casos posibles, especialmente si el máximo fue el primer valor en la lista, pero creo que ahora sí.
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
[]
como se anuncia ("Lista de devolución"). El código debe ser simple if not seq: return []
. (2) El esquema de prueba en bucle es subóptimo: en promedio en listas aleatorias, la condición val < maxval
será la más común, pero el código anterior toma 2 pruebas en lugar de una.
==
lugar de 2: su elif
condición siempre será verdadera.
elif
Cogí el siempre verdadero yo mismo, FWIW. ;-)
Se me ocurrió lo siguiente y funciona como puedes ver max
, min
y otros funcionan en listas como estas:
Por lo tanto, considere la siguiente lista de ejemplo para averiguar la posición del máximo en la lista a
:
>>> a = [3,2,1, 4,5]
Usando el generador enumerate
y haciendo un casting
>>> list(enumerate(a))
[(0, 3), (1, 2), (2, 1), (3, 4), (4, 5)]
En este punto, podemos extraer la posición de max con
>>> max(enumerate(a), key=(lambda x: x[1]))
(4, 5)
Lo anterior nos dice que el máximo está en la posición 4 y su valor es 5.
Como puede ver, en el key
argumento, puede encontrar el máximo sobre cualquier objeto iterable definiendo un lambda apropiado.
Espero que contribuya.
PD: Como señaló @PaulOyster en un comentario. Con Python 3.x
el min
y max
permitir una nueva palabra clave default
que evite la excepción de aumento ValueError
cuando el argumento es una lista vacía.max(enumerate(list), key=(lambda x:x[1]), default = -1)
No puedo reproducir el rendimiento @ SilentGhost-beating citado por @martineau. Aquí está mi esfuerzo con las comparaciones:
=== 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
Resultados de una vieja laptop destacada que ejecuta Python 2.7 en 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
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
Así es como lo hago habitualmente.
También puede usar el paquete numpy:
import numpy as np
A = np.array(a)
maximum_indices = np.where(A==max(a))
Esto devolverá una matriz numpy de todos los índices que contienen el valor máximo
si quieres convertir esto en una lista:
maximum_indices_list = maximum_indices.tolist()
@shash respondió esto en otra parte
Una forma pitónica de encontrar el índice del elemento de lista máximo sería
position = max(enumerate(a), key=lambda x: x[1])[0]
¿Qué pasa uno ? Sin embargo, es más lento que la solución de @Silent_Ghost y, aún más, @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
Aquí está el valor máximo y los índices en los que aparece:
>>> 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]
Más tarde: para satisfacción 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]
heapq
, encontrar el máximo allí sería trivial.
heapq
solución, dudo que funcione.
Idea similar con una lista de comprensión pero sin enumerar
m = max(a)
[i for i in range(len(a)) if a[i] == m]
a[i]
llamada.
Solo una línea:
idx = max(range(len(a)), key = lambda i: a[i])
Si desea obtener los índices de los n
números más grandes en una lista llamada data
, puede usar Pandas sort_values
:
pd.Series(data).sort_values(ascending=False).index[0:n]
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])
Este código no es tan sofisticado como las respuestas publicadas anteriormente, pero funcionará:
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
La lista en el código anterior contendría todas las posiciones del número máximo en la lista.
Puedes hacerlo de varias maneras.
La vieja forma convencional es,
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
Otra forma sin calcular la longitud de la lista y almacenar el valor máximo para cualquier 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)
¡Podemos hacerlo de manera pitónica e inteligente! Usando la comprensión de la lista solo en una línea,
maxIndexList = [i for i,j in enumerate(a) if j==max(a)] #here,i=index and j = value of that index
Todos mis códigos están en Python 3.