Edited at

Python3の...(Ellipsisオブジェクト)について


Ellipsisオブジェクトとは

Python3のREPLで ... と入力してみる。


Python3

>>> ...

Ellipsis

これがEllipsisオブジェクト。

Ellipsis または ... で表されるシングルトンオブジェクトである。

公式リファレンスでは「主に拡張スライス構文やユーザ定義のコンテナデータ型において使われる特殊な値」とあるのみで、明確に用途を定義していない。

英語のellipsisは「省略」という意味なので、処理や引数を省略したい場合に使うものと考えられる。


Noneやpassとの違い


None

None は「値が存在しない」ことを表すが、Ellipsis は「何らかの値が存在するが省略されている」ことを表す。

bool(Ellipsis) の返り値が True である点から見ても、 EllipsisNone よりも肯定的な意味をもつことがわかる。


Python3

>>> bool(None)

False
>>> bool(Ellipsis)
True


pass

pass は文であるが、... は式である。

つまり ... は引数として関数に与えることができる。


Python3

>>> str(Ellipsis)

'Ellipsis'
>>> str(pass)
File "<stdin>", line 1
str(pass)
^
SyntaxError: invalid syntax


使いどころ


実行可能な擬似コード

そもそもPythonは元祖「実行可能な擬似コード」と呼ばれる言語である。

これは、Pythonコードが単なる「実行可能なプログラム」ではなく「人間とコンピュータの双方が理解できる処理やアルゴリズムの表現」であるということ。

擬似コードでは処理などの省略部分を ... と表記することがあるが、Python3はこれを「省略」を表す値として認めることにより、より抽象的な表現を可能にしていると言える。


NumPyでの多次元配列のスライス

より具体的な例。

NumPyでは、多次元配列のスライス記法で ... を使用することができる。

この場合、 ... は指定されていない次元のインデクスが任意であることを示す。


Python3-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]])

スライス記法なら : を使っても同じことができると思うかもしれない。


Python3-NumPy

>>> 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]])


参考