2012-06-28 16 views

Respuesta

33

Dado que ya sabe cómo encontrar el valor mínimo, simplemente ingrese ese valor a la función index() para obtener el índice de este valor en la lista. Es decir,

n = [20, 15, 27, 30] 
n.index(min(n)) 

produce

1 

Esto devolverá el índice del valor mínimo en la lista. Tenga en cuenta que si hay varios mínimos devolverá el primero.

min(): Con un solo argumento iterable, devuelva el elemento más pequeño de un iterable no vacío (como una cadena, tupla o lista). Con más de un argumento, devuelve el más pequeño de los argumentos.

list.index(x): Devuelve el índice en la lista del elemento primera cuyo valor es x. Es un error si no hay tal artículo.

7

Otra opción dependiendo de la complejidad de los datos:

import heapq 
s = [20, 15, 27, 30] 
heapq.nsmallest(1, ((k, i) for i, k in enumerate(s))) 
+1

Esto es (probablemente) más rápido en general, ya los más conocidos peor complejidad caso con destino a la construcción de un montón es O (n), mientras que la comparación los tipos tienen un O (nlog (n)) límite del caso más desfavorable. Sin embargo, aún sería bueno perfilar las dos implementaciones para garantizar que las implementaciones de Python de estas estructuras de datos sean consistentes con los mejores límites de casos. – mvanveen

+0

Me gusta esto porque funcionaría en un iterador. – steveha

10
>>> L = [20, 15, 27, 30] 
>>> min(range(len(L)), key=L.__getitem__) 
1 
5

Esto es similar a la respuesta de @ Jon Clements. Su usa heapq lo que significa que puede usarse para encontrar más de un valor más pequeño. En lugar de usar itemgetter(), simplemente invierte el orden de los valores en las tuplas para que, naturalmente, clasifiquen en el orden correcto.

Si todo lo que necesita es el único valor más pequeño, esta es una manera fácil:

from operator import itemgetter 
lst = [20, 15, 27, 30] 
i, value = min(enumerate(lst), key=itemgetter(1)) 

enumerate() es la forma habitual en Python para emparejar valores de una lista y sus índices; devuelve un iterador que produce tuplas como (i, value) donde value es un valor de la secuencia original y i es el índice de ese valor dentro de la secuencia. min() puede tomar un iterador; el argumento key= se establece en una función que ignora el valor del índice emparejado y solo encuentra el segundo valor mínimo (índice 1) dentro de cada tupla.

min() devuelve la tupla que encuentra con el valor mínimo y luego usamos el desempaquetado tuple para asignar los valores a i y value.

El ejemplo que se muestra es una lista, pero esto podría funcionar con cualquier secuencia que incluye un iterador:

from random import randint 
def rseq(n=20): 
    for i in xrange(n): 
     yield randint(0, 101) 

i, value = min(enumerate(rseq()), key=itemgetter(1)) 

Tenga en cuenta que itemgetter(n) es una fábrica que hace que los objetos se puede llamar. Con itemgetter(1) obtiene un invocable que devuelve el segundo elemento (índice 1) en una secuencia (en este caso, una tupla).También podría escribir una función o una función lambda a hacer lo mismo:

def get1(x): 
    return x[1] 
i, value = min(enumerate(lst), key=get1) 

i, value = min(enumerate(lst), key=lambda x: x[1]) 
+0

Y por supuesto, usar 'itemgetter' (al menos en CPython) toma la ejecución del código fuera de Python y en el nivel C. –

+0

@Jon Clements, me pregunto si sería más rápido simplemente construir las tuplas en orden inverso, como lo hizo tu respuesta. – steveha

+2

Dudo que el rendimiento sea/deba ser un cuello de botella significativamente diferente, aunque he sido corregido anteriormente. Tomando un poco de código de 1 mes para ejecutarlo a 3 días, estoy contento con. Molesto sobre un poco que va desde 2mins54s a 2mins30 - No me puedo molestar - No estoy operando sistemas hospitalarios, y estoy obligado de todos modos, así que :) –

Cuestiones relacionadas