xより大きいリストの最初のインデックスを見つけるための最もPython的な方法は何でしょうか?
たとえば、
list = [0.5, 0.3, 0.9, 0.8]
関数
f(list, 0.7)
戻るだろう
2.
xより大きいリストの最初のインデックスを見つけるための最もPython的な方法は何でしょうか?
たとえば、
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.7nsですが、60000の数値では11.9nsです。
for index, elem in enumerate(elements):
if elem > reference:
return index
raise ValueError("Nothing Found")
1)NUMPY ARGWHERE、一般リスト
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.takewhileは、条件が最初にfalseになると、ループを中断します。
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)