2010-02-10 12 views
41

¿Cuál sería la forma más pitonica de encontrar el primer índice en una lista que es mayor que x?Primer índice de la lista de Python mayor que x?

Por ejemplo, con

list = [0.5, 0.3, 0.9, 0.8] 

La función

f(list, 0.7) 

volvería

2. 
+29

no utilizan 'lista' como nombre de variable ... – mshsayem

+9

Usted quiere decir "Pythonic". Según http://www.urbandictionary.com/define.php?term=Pythonesque, "pythonesque" significa "surrealista, absurdo", y no creo que sea eso lo que está buscando: P –

+1

La pregunta es ambigua . ¿La respuesta es '2' porque' 0.9> 0.7' o porque '0.8> 0.7'? En otras palabras, ¿estás buscando secuencialmente o en el orden de valores crecientes? – osa

Respuesta

57
next(x[0] for x in enumerate(L) if x[1] > 0.7) 
+17

1: Aunque yo preferiría evitar los números mágicos: al lado (IDX para IDX, el valor de enumeración (L) Si el valor> 0,7) – truppo

+22

1 por simplicidad y 'siguiente()', pero tal vez esto para facilitar la lectura: ' siguiente (i para i, v en enumerate (L) if v> 0.7) ' –

+6

Si bien es bonito, el caso en el que no hay resultados generará una confusión de StopIteration. –

0
>>> f=lambda seq, m: [ii for ii in xrange(0, len(seq)) if seq[ii] > m][0] 
>>> f([.5, .3, .9, .8], 0.7) 
2 
+0

Eso se ve bastante resbaladizo. Pero teóricamente atravesará toda la lista y luego devolverá el primer resultado (mayor que x), ¿verdad? ¿Hay alguna manera de hacer uno que se detenga después de encontrar el primer resultado? – c00kiemonster

+0

sí, atraviesa toda la lista – flybywire

+0

¿qué hay de malo en atravesar toda la lista? si el primer valor mayor que 0,7 está cerca del final de la lista, no hace la diferencia. – ghostdog74

4
for index, elem in enumerate(elements): 
    if elem > reference: 
     return index 
raise ValueError("Nothing Found") 
9
>>> alist= [0.5, 0.3, 0.9, 0.8] 
>>> [ n for n,i in enumerate(alist) if i>0.7 ][0] 
2 
+0

me gano :) –

+1

fallará si 'x' es mayor que cualquier otro valor en la lista – mshsayem

+1

@mshsayem: El problema está mal definido para este caso. El fracaso puede ser lo correcto. –

2

Otra:

map(lambda x: x>.7, seq).index(True) 
11
filter(lambda x: x>.7, seq)[0] 
+1

-1: Si bien es técnicamente correcto, no utilice el filtro donde la comprensión de la lista sea más legible y más eficaz – truppo

+0

filtro (lambda x: x [1]> .7, enumerar (seq)) [0] [0] - lineal simple search – lowtech

+1

@truppo filter in python 3 devuelve un generador, por lo que no debería ser peor que una lista de comprensión? También me parece más fácil de leer que la solución de enumerar. – BubuIIC

11

si la lista está ordenada a continuación bisect_left(alist, value) es más rápido para obtener una lista grande que next(i for i, x in enumerate(alist) if x >= value).

1

Tuve un problema similar cuando mi lista era muy larga. la comprensión o las soluciones basadas en filtros pasarían a toda la lista. itertools.takewhile romperá el bucle una vez que se convierten en condición falsa primera vez:

from itertools import takewhile 

def f(l, b): return len([x for x in takewhile(lambda x: x[1] <= b, enumerate(l))]) 

l = [0.5, 0.3, 0.9, 0.8] 
f(l, 0.7) 
Cuestiones relacionadas