Was wäre der pythonischste Weg, um den ersten Index in einer Liste zu finden, der größer als x ist?
Zum Beispiel mit
list = [0.5, 0.3, 0.9, 0.8]
Die Funktion
f(list, 0.7)
würden zurückkehren
2.
Was wäre der pythonischste Weg, um den ersten Index in einer Liste zu finden, der größer als x ist?
Zum Beispiel mit
list = [0.5, 0.3, 0.9, 0.8]
Die Funktion
f(list, 0.7)
würden zurückkehren
2.
2
weil 0.9 > 0.7
oder weil 0.8 > 0.7
? Mit anderen Worten, suchen Sie nacheinander oder in der Reihenfolge steigender Werte?
Antworten:
next(x[0] for x in enumerate(L) if x[1] > 0.7)
next()
, aber vielleicht für die Lesbarkeit:next(i for i,v in enumerate(L) if v > 0.7)
next()
ist in 2.6+. Nennen Sie die next()
Methode des Genex in früheren Versionen.
itertools.chain()
diese Option, anstatt solche Listen hinzuzufügen.
Wenn die Liste sortiert ist, bisect.bisect_left(alist, value)
ist sie für eine große Liste schneller als next(i for i, x in enumerate(alist) if x >= value)
.
bisect_left
ist O (log n), während listcomp O (n) ist, dh je größer der n
, desto mehr Vorteil auf der bisect_left()
Seite. Ich habe versucht , finden Index 500_000
in range(10**6)
Verwendung bisect_left()
-> 3,75 Mikrosekunden und mit Hilfe des genexpr mit next()
-> 51,0 Millisekunden [ 10_000
mal] langsamer als erwartet.
filter(lambda x: x>.7, seq)[0]
bisect_left()
(am schnellsten) und enumerate()
.
>>> alist= [0.5, 0.3, 0.9, 0.8]
>>> [ n for n,i in enumerate(alist) if i>0.7 ][0]
2
IndexError: list index out of range
. Die Verwendung von index = next[ n for n,i in enumerate(alist) if i>0.7 ]
Fehler ergibt : NameError: name 'index' is not defined
. next
ist etwas schneller: Der Zeitunterschied beträgt 12,7 ns gegenüber 11,9 ns für 60 000 Nummern.
for index, elem in enumerate(elements):
if elem > reference:
return index
raise ValueError("Nothing Found")
Ich hatte ein ähnliches Problem, als meine Liste sehr lang war. Verständnis oder filterbasierte Lösungen würden die ganze Liste durchlaufen. itertools.takewhile unterbricht die Schleife, sobald die Bedingung beim ersten Mal falsch wird:
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)
Ich weiß, dass es bereits viele Antworten gibt, aber manchmal habe ich das Gefühl, dass das Wort Python in "Einzeiler" übersetzt wird.
Wenn ich denke, dass eine bessere Definition dieser Antwort näher kommt :
"Nutzen Sie die Funktionen der Python-Sprache, um Code zu erstellen, der klar, präzise und wartbar ist."
Obwohl einige der oben genannten Antworten prägnant sind, finde ich sie nicht klar und es würde eine Weile dauern, bis ein Programmieranfänger sie versteht, sodass sie für ein Team mit vielen Fähigkeiten nicht besonders wartbar sind.
l = [0.5, 0.3, 0.9, 0.8]
def f(l, x):
for i in l:
if i >x: break
return l.index(i)
f(l,.7)
oder
l = [0.5, 0.3, 0.9, 0.8]
def f(l, x):
for i in l:
if i >x: return l.index(i)
f(l,.7)
Ich denke, dass das Obige für einen Neuling leicht verständlich ist und immer noch prägnant genug ist, um von jedem erfahrenen Python-Programmierer akzeptiert zu werden.
Ich denke, das Schreiben von dummem Code ist positiv.
1) NUMPY SOLUTION, allgemeine Listen
Wenn Sie gerne numpy verwenden, funktioniert Folgendes für allgemeine Listen (sortiert oder unsortiert):
numpy.argwhere(np.array(searchlist)>x)[0]
oder wenn Sie die Antwort als Liste benötigen:
numpy.argwhere(np.array(searchlist)>x).tolist()[0]
oder wenn Sie die Antwort als ganzzahligen Index benötigen:
numpy.argwhere(np.array(searchlist)>x).tolist()[0][0]
2) NUMPY SOLUTION, sortierte Listen
Wenn Ihre Suchliste jedoch sortiert ist, ist es viel sauberer und schöner, die Funktion np.searchsorted zu verwenden :
numpy.searchsorted(searchlist,x)
Das Schöne an dieser Funktion ist, dass Sie neben der Suche nach einem einzelnen Wert x auch eine Liste von Indizes für eine Liste von Werten x zurückgeben können ( und dies ist in diesem Fall im Vergleich zum Listenverständnis sehr effizient ).
>>> 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
Sie können dies auch tun mit numpy
:
import numpy as np
list(np.array(SearchList) > x).index(True)
Probier diese:
def Renumerate(l):
return [(len(l) - x, y) for x,y in enumerate(l)]
Beispielcode:
Renumerate(range(10))
Ausgabe:
(10, 0)
(9, 1)
(8, 2)
(7, 3)
(6, 4)
(5, 5)
(4, 6)
(3, 7)
(2, 8)
(1, 9)