リストitems
に変更を加えずにitems[i]
を除いたリストを得るのに最も速い書き方あるいは,そこそこ速くてスマートな書き方が気になります(数学でたまに i 番目を除く,みたいなのが欲しくなるので).
Jupyter の %timeit
で計測してみました.
numpyを使わない場合
items = list(range(1000000))
i = 17 #適当
スライスの結合
%timeit items[:i] + items[i+1:]
11.2 ms ± 349 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
内包表記(enumerate
使用)
%timeit [item for k, item in enumerate(items) if k != i]
65.1 ms ± 212 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
内包表記
%timeit [items[k] for k in range(len(items)) if k != i]
75.5 ms ± 800 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
スライスの結合の方が圧倒的に速いようです.ちなみに3番目の例より,2番目のenumerate
を使った方が速いのはちょっと驚きました.
numpyを使う場合
@antimon2 さんの丸パクですが,以下のような方法があります.
import numpy as np
items = np.arange(1000000)
i = 17
np.hstack
%timeit np.hstack([items[:i], items[i+1:]])
584 µs ± 6.32 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
np.delete
%timeit np.delete(items, i)
585 µs ± 3.73 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
ブールインデックス
%timeit items[np.arange(items.size) != i]
1.9 ms ± 5.82 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
内包表記
%timeit np.array([items[k] for k in range(len(items)) if k != i])
182 ms ± 3.85 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
こちらもやはりスライスの結合がとても速いです.可読性を考えるとそんなに速さが変わらない np.delete
がベストでしょうか.
もし,他によいものがあればご教示ください.