Яким би був найбільш пітонічний спосіб знайти перший індекс у списку, який перевищує x?
Наприклад, с
list = [0.5, 0.3, 0.9, 0.8]
Функція
f(list, 0.7)
повернувся б
2.
Яким би був найбільш пітонічний спосіб знайти перший індекс у списку, який перевищує x?
Наприклад, с
list = [0.5, 0.3, 0.9, 0.8]
Функція
f(list, 0.7)
повернувся б
2.
2тому 0.9 > 0.7чи тому 0.8 > 0.7? Іншими словами, ви шукаєте послідовно або в порядку збільшення значень?
Відповіді:
next(x[0] for x in enumerate(L) if x[1] > 0.7)
next(), але, можливо, це для читабельності:next(i for i,v in enumerate(L) if v > 0.7)
itertools.chain()замість додавання таких списків.
next((i for i, x in enumerate(L) if x > value), -1)
якщо список відсортований, то bisect.bisect_left(alist, value)швидший для великого списку, ніж next(i for i, x in enumerate(alist) if x >= value).
bisect_leftдорівнює O (log n), тоді як listcomp дорівнює O (n), тобто чим більше n, тим більше переваг bisect_left()збоку. Я намагався знайти індекс 500_000в range(10**6)використанні bisect_left()-> 3,75 мікросекунди і використовуючи genexpr з next()-> 51,0 мілісекунди [ 10_000раз] повільніше , як очікувалося.
filter(lambda x: x>.7, seq)[0]
bisect_left()(найшвидший) та 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. Використання index = next[ n for n,i in enumerate(alist) if i>0.7 ]помилки дає: NameError: name 'index' is not defined. nextтрохи швидше: різниця у часі становить 12,7 нс проти 11,9 нс для 60 000 чисел.
for index, elem in enumerate(elements):
if elem > reference:
return index
raise ValueError("Nothing Found")
1) НУМІ СЕРЕД, загальні списки
Якщо ви із задоволенням користуєтесь numpy, то в загальних списках (відсортованих чи невідсортованих) буде працювати наступне:
numpy.argwhere(np.array(searchlist)>x)[0]
або якщо вам потрібна відповідь у вигляді списку:
numpy.argwhere(np.array(searchlist)>x).tolist()[0]
або якщо вам потрібна відповідь як цілочисельний індекс:
numpy.argwhere(np.array(searchlist)>x).tolist()[0][0]
2) NUMPY SEARCHSORTED, відсортовані списки (дуже ефективно для пошуку списків)
Однак, якщо ваш список пошуку відсортований, набагато чистіше і приємніше використовувати функцію np.searchsorted :
numpy.searchsorted(searchlist,x)
Приємна річ використання цієї функції полягає в тому, що окрім пошуку одного значення x, x також може бути списком, тобто ви також можете повернути список індексів для списку шуканих значень [x1, x2, x3 .. xn ], ( і в цьому випадку це дуже ефективно щодо розуміння списку ).
У мене була подібна проблема, коли мій список був дуже довгим. розуміння або рішення, засновані на фільтрах, пройшли б через цілий список. itertools.takegether розірве цикл, коли умова вперше стане хибним:
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)
Я знаю, що вже є багато відповідей, але іноді я відчуваю, що слово pythonic перекладається на "однокласний".
Коли я думаю, що краще визначення є ближчим до цієї відповіді :
"Використання особливостей мови Python для створення чіткого, стислого та ремонтопридатного коду."
Хоча деякі з вищезазначених відповідей стислі, я не вважаю їх чіткими, і програмісту-новачку знадобиться деякий час, щоб зрозуміти, отже, не роблячи їх надзвичайно рентабельними для команди, складеної з багатьох рівнів кваліфікації.
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)
або
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)
Я думаю, що вищезазначене легко зрозуміти новачкові і все ще досить стисло, щоб прийняти його будь-яким ветераном-програмістом на python.
Я думаю, що написання німого коду - це позитив.
>>> 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
Ви також можете зробити це за допомогою numpy:
import numpy as np
list(np.array(SearchList) > x).index(True)
Спробуйте це:
def Renumerate(l):
return [(len(l) - x, y) for x,y in enumerate(l)]
приклад коду:
Renumerate(range(10))
вихід:
(10, 0)
(9, 1)
(8, 2)
(7, 3)
(6, 4)
(5, 5)
(4, 6)
(3, 7)
(2, 8)
(1, 9)