Exploring Python’s Ellipsis (…) : More than Just Syntax Sugar
Ever wondered what the three dots (...) in Python are used for? Discover how this powerful operator can simplify your code!

Image by Author | Canva
Python, a language known for its power, has a few hidden gems that don’t always get the importance it deserves. As per the topic, we claim that the ellipsis is one such feature, with uses that programmers do not usually know. In simple terms, the ellipsis is a three dot symbol used like a placeholder to highlight the unfinished code or areas where future work is planned. The ellipsis makes it easier to slice multidimensional arrays and is useful in type hinting. Hence, we can say that the ellipsis is a tool that can improve code, enabling more organized code while simplifying complex operations.
You don't need to import the ellipsis to use it. Let’s now dive deeper to understand what ellipsis has to offer.
1. Ellipsis as Placeholder
Mostly in the English language, three dots signal continuation or depict skipped portions. Similarly, in Python, the ellipsis can act like a carrier for code that has not been implemented until now. This approach is especially useful when you’re structuring functions, classes, or even entire modules, allowing you to leave parts of the code empty without causing syntax errors.
For example, if you’re designing a program and know the code structure yet haven’t written all the logic, you can use ... to hold the place where code will eventually go:
def classify():
...
In this context, the ellipsis acts like a "to-do" marker, indicating that there is more work to be done. Unlike pass, which acts like a no-operation placeholder, using ... (the ellipsis) indicates that a function is intentionally incomplete.
2. Ellipsis in Slicing Multidimensional Arrays
The ellipsis operator in Python is a valuable tool for array slicing, especially in libraries like NumPy where handling multi-dimensional arrays can get complex. Consider a 3D array arr where you want to select all elements along the first two dimensions while retrieving elements at index 0 of the last dimension. Using the ellipsis operator, you can do this with:
import numpy as np
# Create a 3D array
arr = np.arange(27).reshape(3, 3, 3)
# Select all elements along the first two dimensions and only index 0 of the last dimension
result = arr[..., 0]
print(result)
Output
[[ 0 3 6]
[ 9 12 15]
[18 21 24]]
The arr[..., 0] selects all elements along the first two dimensions while focusing only on index 0 in the third dimension. This approach makes high-dimensional data manipulation efficient and improves code clarity when working with large datasets.
3. Ellipsis in Default Parameter Values
The ellipsis (...) can also be used as a unique default parameter value in Python functions, providing a helpful alternative when None could be a valid argument. By using ... as a default, you can clearly distinguish between cases where no argument was provided and cases where None is intentionally passed as a value.
Let’s understand it with the help of an example:
def greet(name="Guest", greeting=...):
if greeting is ...:
greeting = "Hello" # Default greeting if none provided
print(f"{greeting}, {name}!")
# Testing different cases
greet("Alice") # Uses default greeting: "Hello, Alice!"
greet("Bob", greeting="Hi") # Custom greeting: "Hi, Bob!"
greet("Charlie", greeting=None)
# Outputs: "None, Charlie!" (explicitly setting greeting to None)
In this example:
- If greeting is not provided, it defaults to "Hello".
- If a specific greeting is provided (like "Hi"), the function uses that instead of the default.
- If greeting=None, it displays "None, {name}!", showing that None was passed on purpose, distinct from using the default.
4. Ellipsis As Type Hints
The ellipsis (...) can be used as type hints, especially in certain contexts where you want to indicate that more values could be present or that something has a variable structure that is not fully specified. Following are the two different uses of ellipsis as type hints we are going to discuss:
For Tuples of Unknown Length
Type Hints are used to represent elements that are flexible or have unspecified characteristics. Imagine if you want to create a variable called grocery_list that is a tuple of strings, but you don’t know how many strings will be in that tuple. Ellipsis ensures that all elements are strings while allowing the number of elements to vary.
Code Example:
from typing import Tuple
# Allowed:
grocery_list: Tuple[str, ...] = ("apples", "bread", "milk", "eggs", "butter")
grocery_list = ("apples",) # A tuple with a single string is allowed
grocery_list = () # An empty tuple is allowed
# Not allowed:
grocery_list = (1, "bread")
grocery_list = ["apples", "bread"]
grocery_list = ("apples", 2.5)
# Function to print each item in the grocery list
def print_grocery_items(items: Tuple[str, ...]) -> None:
for item in items:
print(f"- {item}")
# Call the function with our grocery list
print_grocery_items(grocery_list)
The variable definition like grocery_list: Tuple[str, ...] = ("apples", "bread") is valid because both elements are of the specified type, while mixed types like (1, "bread") or a list instead of a tuple ["apples", "bread"] are not allowed.
For Callables with Flexible Arguments
Ellipsis can be used in type hints for callables when the number and types of arguments are unknown. At times, you may need to pass a function to another function without knowing what the arguments to that function will be. So ellipsis can be used to show that the function can take optional number of arguments of any type.
Code Example:
from typing import Callable
# A function that takes one number and returns it doubled
def double_value(x: int) -> int:
return x * 2
# A function that takes two numbers and returns their sum
def add_values(x: int, y: int) -> int:
return x + y
# A function that takes an integer, a callable, and optional extra arguments
def apply_action(value: int, action: Callable[..., int], *args: int) -> int:
return action(value, *args)
# Allowed:
print(apply_action(5, double_value)) # Calls double_value(5), which results in 10
print(apply_action(5, add_values, 3)) # Calls add_values(5, 3), which results in 8
# Not Allowed:
apply_action(5, 3)
apply_action(5, double_value, "extra")
In the above example,
- The function apply_action takes an integer (value), a callable (action), and optional additional arguments (*args).
- The type hint Callable[..., int] means that the action callable can take any number of arguments of any type, but it must return an int.
- The apply_action function can handle both scenarios of functions double_value and add_values because of the ellipsis (...) in the type hint.
- The examples that do not work highlight that the callable must be a function and that the extra arguments must match the function's expected input type.
This maintains type consistency while providing flexibility in the arguments passed to the callable.
Wrapping Up
In summary, the ellipsis (...) in Python is often an underappreciated feature that can improve coding efficiency. By integrating the ellipsis into your coding toolkit, you can write cleaner and more organized code.
Kanwal Mehreen is a machine learning engineer and a technical writer with a profound passion for data science and the intersection of AI with medicine. She co-authored the ebook "Maximizing Productivity with ChatGPT". As a Google Generation Scholar 2022 for APAC, she champions diversity and academic excellence. She's also recognized as a Teradata Diversity in Tech Scholar, Mitacs Globalink Research Scholar, and Harvard WeCode Scholar. Kanwal is an ardent advocate for change, having founded FEMCodes to empower women in STEM fields.