与えられたリストからいくつかの要素を選び、それらのインデックスを知る必要があります。与えられたリスト[-2、1、5、3、8、5、6]から、インデックス1、2、5の要素を含む新しいリストを作成したいとしましょう。私がしたことは、
a = [-2,1,5,3,8,5,6]
b = [1,2,5]
c = [ a[i] for i in b]
もっと良い方法はありますか? c = a [b]のようなもの?
operator.itemgetter
を使うことができます。
from operator import itemgetter
a = [-2, 1, 5, 3, 8, 5, 6]
b = [1, 2, 5]
print(itemgetter(*b)(a))
# Result:
(1, 5, 5)
または、 numpy を使用することもできます。
import numpy as np
a = np.array([-2, 1, 5, 3, 8, 5, 6])
b = [1, 2, 5]
print(list(a[b]))
# Result:
[1, 5, 5]
しかし、実際には、現在の解決策は問題ありません。それはおそらくそれらすべての中で最も新しいです。
代替案:
>>> map(a.__getitem__, b)
[1, 5, 5]
>>> import operator
>>> operator.itemgetter(*b)(a)
(1, 5, 5)
別の解決策はパンダシリーズを介してすることができます:
import pandas as pd
a = pd.Series([-2, 1, 5, 3, 8, 5, 6])
b = [1, 2, 5]
c = a[b]
必要に応じて、cをリストに戻すことができます。
c = list(c)
提供された5つの答えの実行時間を比較した、基本的なテストで、あまり広範囲ではありません。
def numpyIndexValues(a, b):
na = np.array(a)
nb = np.array(b)
out = list(na[nb])
return out
def mapIndexValues(a, b):
out = map(a.__getitem__, b)
return list(out)
def getIndexValues(a, b):
out = operator.itemgetter(*b)(a)
return out
def pythonLoopOverlap(a, b):
c = [ a[i] for i in b]
return c
multipleListItemValues = lambda searchList, ind: [searchList[i] for i in ind]
次のように入力します。
a = range(0, 10000000)
b = range(500, 500000)
単純なpythonループはラムダ演算のすぐ近くにあり、mapIndexValuesとgetIndexValuesは一貫してnumpyメソッドとかなり似ていました。最速です。
numpyIndexValues -> time:1.38940598 (when converted the lists to numpy arrays)
numpyIndexValues -> time:0.0193445 (using numpy array instead of python list as input, and conversion code removed)
mapIndexValues -> time:0.06477512099999999
getIndexValues -> time:0.06391049500000001
multipleListItemValues -> time:0.043773591
pythonLoopOverlap -> time:0.043021754999999995
私はこれがすでに考慮されていると確信しています:bの中のインデックスの量が小さくて一定であるならば、ただ次のような結果を書くことができます:
c = [a[b[0]]] + [a[b[1]]] + [a[b[2]]]
あるいは、インデックス自体が定数の場合はもっと単純です。
c = [a[1]] + [a[2]] + [a[5]]
または連続した範囲のインデックスがある場合...
c = a[1:3] + [a[5]]
私の答えは、でこぼこやPythonのコレクションを使用していません。
要素を見つけるための簡単な方法は次のとおりです。
a = [-2, 1, 5, 3, 8, 5, 6]
b = [1, 2, 5]
c = [i for i in a if i in b]
欠点:この方法は大きなリストでは動作しないかもしれません。大きなリストの場合は、numpyを使用することをお勧めします
あなたの例のように、リストが小さく、インデックスが変更されない場合、 sequence unpacking を使用することが最善の場合があることを忘れないでください。
_,a1,a2,_,_,a3,_ = a
パフォーマンスは大幅に向上し、1行のコードを保存することもできます。
%timeit _,a1,b1,_,_,c1,_ = a
10000000 loops, best of 3: 154 ns per loop
%timeit itemgetter(*b)(a)
1000000 loops, best of 3: 753 ns per loop
%timeit [ a[i] for i in b]
1000000 loops, best of 3: 777 ns per loop
%timeit map(a.__getitem__, b)
1000000 loops, best of 3: 1.42 µs per loop