LoginSignup
6
6

More than 5 years have passed since last update.

インデックスが i の要素を除いたリストを得るには……?

Last updated at Posted at 2017-08-30

リスト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 がベストでしょうか.

もし,他によいものがあればご教示ください.

6
6
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6