Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

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

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

HigashinoSola
EPUB3 + MathML に興味あり.Pythonと数学が相性良さげでよく使ってます.
https://mathfob.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away