Solving problem is about exposing yourself to as many situations as possible like What does the Ellipsis object do? and practice these strategies over and over. With time, it becomes second nature and a natural way you approach any problems in general. Big or small, always start with a plan, use other strategies mentioned here till you are confident and ready to code the solution.
In this post, my aim is to share an overview the topic about What does the Ellipsis object do?, which can be followed any time. Take easy to follow this discuss.
While idly surfing the namespace I noticed an odd looking object called Ellipsis
, it does not seem to be or do anything special, but it’s a globally available builtin.
After a search I found that it is used in some obscure variant of the slicing syntax by Numpy and Scipy… but almost nothing else.
Was this object added to the language specifically to support Numpy + Scipy? Does Ellipsis have any generic meaning or use at all?
D:workspacenumpy>python
Python 2.4.4 (#71, Oct 18 2006, 08:34:43) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> Ellipsis
Ellipsis
Answer #1:
This came up in another question recently. I’ll elaborate on my answer from there:
Ellipsis is an object that can appear in slice notation. For example:
myList[1:2, ..., 0]
Its interpretation is purely up to whatever implements the __getitem__
function and sees Ellipsis
objects there, but its main (and intended) use is in the numpy third-party library, which adds a multidimensional array type. Since there are more than one dimensions, slicing becomes more complex than just a start and stop index; it is useful to be able to slice in multiple dimensions as well. E.g., given a 4×4 array, the top left area would be defined by the slice [:2,:2]
:
>>> a
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12],
[13, 14, 15, 16]])
>>> a[:2,:2] # top left
array([[1, 2],
[5, 6]])
Extending this further, Ellipsis is used here to indicate a placeholder for the rest of the array dimensions not specified. Think of it as indicating the full slice [:]
for all the dimensions in the gap it is placed, so for a 3d array, a[...,0]
is the same as a[:,:,0]
and for 4d, a[:,:,:,0]
, similarly, a[0,...,0]
is a[0,:,:,0]
(with however many colons in the middle make up the full number of dimensions in the array).
Interestingly, in python3, the Ellipsis literal (...
) is usable outside the slice syntax, so you can actually write:
>>> ...
Ellipsis
Other than the various numeric types, no, I don’t think it’s used. As far as I’m aware, it was added purely for numpy use and has no core support other than providing the object and corresponding syntax. The object being there didn’t require this, but the literal “…” support for slices did.
Answer #2:
In Python 3, you can¹ use the Ellipsis literal ...
as a “nop” placeholder for code that hasn’t been written yet:
def will_do_something():
...
This is not magic; any expression can be used instead of ...
, e.g.:
def will_do_something():
1
(Can’t use the word “sanctioned”, but I can say that this use was not outrightly rejected by Guido.)
¹ 'can' not in {'must', 'should'}
Answer #3:
As of Python 3.5 and PEP484, the literal ellipsis is used to denote certain types to a static type checker when using the typing module.
Example 1:
Arbitrary-length homogeneous tuples can be expressed using one type and ellipsis, for example
Tuple[int, ...]
Example 2:
It is possible to declare the return type of a callable without specifying the call signature by substituting a literal ellipsis (three dots) for the list of arguments:
def partial(func: Callable[..., str], *args) -> Callable[..., str]:
# Body
Answer #4:
You can also use the Ellipsis when specifying expected doctest output:
class MyClass(object):
"""Example of a doctest Ellipsis
>>> thing = MyClass()
>>> # Match <class '__main__.MyClass'> and <class '%(module).MyClass'>
>>> type(thing) # doctest:+ELLIPSIS
<class '....MyClass'>
"""
pass
Answer #5:
Summing up what others have said, as of Python 3, Ellipsis is essentially another singleton constant similar to None
, but without a particular intended use. Existing uses include:
- In slice syntax to represent the full slice in remaining dimensions
- In type hinting to indicate only part of a type(
Callable[..., int]
orTuple[str, ...]
) - In type stub files to indicate there is a default value without specifying it
Possible uses could include:
- As a default value for places where
None
is a valid option - As the content for a function you haven’t implemented yet
Answer #6:
From the Python documentation:
This object is commonly used by slicing (see Slicings). It supports no
special operations. There is exactly one ellipsis object, named
Ellipsis (a built-in name).type(Ellipsis)()
produces the Ellipsis
singleton.It is written as
Ellipsis
or...
.
Answer #7:
__getitem__
minimal ...
example in a custom class
When the magic syntax ...
gets passed to []
in a custom class, __getitem__()
receives a Ellipsis
class object.
The class can then do whatever it wants with this Singleton object.
Example:
class C(object):
def __getitem__(self, k):
return k
# Single argument is passed directly.
assert C()[0] == 0
# Multiple indices generate a tuple.
assert C()[0, 1] == (0, 1)
# Slice notation generates a slice object.
assert C()[1:2:3] == slice(1, 2, 3)
# Ellipsis notation generates the Ellipsis class object.
# Ellipsis is a singleton, so we can compare with `is`.
assert C()[...] is Ellipsis
# Everything mixed up.
assert C()[1, 2:3:4, ..., 6] == (1, slice(2,3,4), Ellipsis, 6)
The Python built-in list
class chooses to give it the semantic of a range, and any sane usage of it should too of course.
Personally, I’d just stay away from it in my APIs, and create a separate, more explicit method instead.
Tested in Python 3.5.2 and 2.7.12.
Answer #8:
You can use Ellipsis yourself, in custom slicing situations like numpy has done, but it has no usage in any builtin class.
I don’t know if it was added specifically for use in numpy, but I certainly haven’t seen it used elsewhere.
See also: How do you use the ellipsis slicing syntax in Python?