やりたいこと
タイトルの通り,リストから複数のインデックスを指定して値を操作する.
環境
python 3.6.6
numpy 1.12.1
指定した複数のインデックスの値を取得
input
sentence = ["why","japanese","people","!!"]
イメージとしてはsentence[0,2]
とした時に['why','people']
が取れてほしい.
ではどうするか...
python3
from operator import itemgetter
print (itemgetter(0,2)(sentence)) # ('why', 'people')
itemgetter
はpython2.5以降から使えるようになったみたい.それ以前は内包表記などでベタ書きだったのか?その方がわかりやすい気もするが.
ランダムな複数のインデックスの値を取得
インデックスの指定をランダムにするだけ.2つのリストから複数の同じインデックスで値を取得したい時に.
np.random.choice
の引数replace
を指定しなければ,重複ありでサンプルする.
python3
from operator import itemgetter
import numpy as np
datasetA = ["a","b","c","d"]
datasetB = [1,2,3,4]
data_size = len(datasetA)
sample_size = 2
shuffled_idx = np.random.choice(np.arange(data_size), sample_size, replace=False)
datasetA_random_pickup = itemgetter(*shuffled_idx)(datasetA)
datasetB_random_pickup = itemgetter(*shuffled_idx)(datasetB)
複数の指定したインデックスを削除
input
sentence = ["why","japanese","people","!!"]
イメージとしてはdel sentence[0,2]
とした時に['japanese','!!']
だけ残ってほしい.
ではどうするか...
python3
dellist = lambda items,indices: [item for idx,item in enumerate(items) if idx not in indices]
del_idx = [0,2] # 削除するインデックス
sentence_deleted = dellist(sentence, del_idx) # ['japanese','!!']
結局,内包表記で行う操作をdellist
というラムダ式で隠蔽してるだけ.
itemgetter
の削除バージョンのようなものはないのだろうか…
追記(2019.7.22)
itemgetter
の仕様に合わせた、itemremover
なるものを自作するとすれば以下のような関数になります。
@shiracamus さんのコメントより。ありがとうございます!
python
def itemremover(*items):
def g(obj):
if hasattr(obj, 'keys'):
return tuple(obj[key] for key in obj.keys() if key not in items)
if len(items) == 1:
if isinstance(obj, str):
o = list(obj)
del o[items[0]]
return ''.join(o)
else:
o = list(obj)
del o[items[0]]
return tuple(o)
if isinstance(obj, str):
return ''.join(o for index, o in enumerate(obj) if index not in items)
else:
return tuple(o for index, o in enumerate(obj) if index not in items)
return g
まとめ
itemremover
、公式実装されないかな…