Ellipsisオブジェクトとは
Python3のREPLで ...
と入力してみる。
>>> ...
Ellipsis
これがEllipsisオブジェクト。
Ellipsis
または ...
で表されるシングルトンオブジェクトである。
公式リファレンスでは「主に拡張スライス構文やユーザ定義のコンテナデータ型において使われる特殊な値」とあるのみで、明確に用途を定義していない。
英語のellipsisは「省略」という意味なので、処理や引数を省略したい場合に使うものと考えられる。
Noneやpassとの違い
None
None
は「値が存在しない」ことを表すが、Ellipsis
は「何らかの値が存在するが省略されている」ことを表す。
bool(Ellipsis)
の返り値が True
である点から見ても、 Ellipsis
が None
よりも肯定的な意味をもつことがわかる。
>>> bool(None)
False
>>> bool(Ellipsis)
True
pass
pass
は文であるが、...
は式である。
つまり ...
は引数として関数に与えることができる。
>>> str(Ellipsis)
'Ellipsis'
>>> str(pass)
File "<stdin>", line 1
str(pass)
^
SyntaxError: invalid syntax
使いどころ
実行可能な擬似コード
そもそもPythonは元祖「実行可能な擬似コード」と呼ばれる言語である。
これは、Pythonコードが単なる「実行可能なプログラム」ではなく「人間とコンピュータの双方が理解できる処理やアルゴリズムの表現」であるということ。
擬似コードでは処理などの省略部分を ... と表記することがあるが、Python3はこれを「省略」を表す値として認めることにより、より抽象的な表現を可能にしていると言える。
NumPyでの多次元配列のスライス
より具体的な例。
NumPyでは、多次元配列のスライス記法で ...
を使用することができる。
この場合、 ...
は指定されていない次元のインデクスが任意であることを示す。
>>> import numpy
>>> a = numpy.array([[1, 2],
... [3, 4]]) # 2x2の多次元配列
>>> a[0, ...] # 0行目の任意の列の要素からなる配列
array([1, 2])
>>> a[1, ...] # 1行目の任意の列の要素からなる配列
array([3, 4])
>>> a[..., 0] # 任意の行の0列目の要素からなる配列
array([1, 3])
>>> a[..., 1] # 任意の行の1列目の要素からなる配列
array([2, 4])
>>> a[...] # 任意の行の任意の列の要素からなる配列
array([[1, 2],
[3, 4]])
スライス記法なら :
を使っても同じことができると思うかもしれない。
>>> a[0, :]
array([1, 2])
しかし、3次元以上の配列では :
と ...
の動作が異なる。
:
はあくまで特定のひとつの次元が任意であることを示すが、 ...
は指定されていない全ての次元について、インデックスが任意であることを示す。
>>> b = numpy.array([[[1, 2],
... [3, 4]],
... [[5, 6],
... [7, 8]]]) # 2x2x2の多次元配列
>>> b[..., 0] # 第1, 2次元は任意、第3次元のインデックスは0 ---(1)
array([[1, 3],
[5, 7]])
>>> b[:, :, 0] # (1)と同義
array([[1, 3],
[5, 7]])
>>> b[:, 0] # 第1次元は任意、第2次元のインデックスは0、第3次元のインデックスは任意 ---(2)
array([[1, 2],
[5, 6]])
>>> b[:, 0, :] # (2)と同義
array([[1, 2],
[5, 6]])