Fancy Indexingが使えるリストを実装してみた

自分用のメモ。Pythonでlistにデータを入れてnumpyみたいにインデックスをリストでわたして取り出したいと思ったので作ってみた。

実装はこちら。

from collections import UserList
#class FancyIndexingList(list): 2020/02/03修正。UserListを継承すべき
class FancyIndexingList(UserList):
	def __getitem__(self, arg):
		if not isinstance(arg, list) and not isinstance(arg, tuple):
			return super().__getitem__(arg)

		indices = arg
		result = [self[i] for i in indices]
		return FancyIndexingList(result)

UserListを継承して__getitem__で引数がリストとタプルの時だけ自分で処理して他は全部親クラスに任せる。
Fancy Indexingは__getitem__の引数がそのままインデックスのリストになっているので、インデックス引きして新しいリストを作って返すだけ。

使うときはこんな感じ。

>>> sample = FancyIndexingList(range(10))
>>> sample
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> sample[2]
2
>>> sample[ [4, 2, 0] ]
[4, 2, 0]


参考。

>>> class IndexingTest:
...     def __getitem__(self, arg):
...             print(type(arg))
...
>>> i = IndexingTest()
>>> i[1]
<class 'int'>
>>> i[1, 2]
<class 'tuple'>
>>> i[ [0, 1] ]
<class 'list'>
>>> i[0:10:2]
<class 'slice'>