Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Farama Foundation Gymnasium Tuple Space

From Leeroopedia
Knowledge Sources
Domains Reinforcement_Learning, Spaces
Last Updated 2026-02-15 03:00 GMT

Overview

Concrete tool for representing the cartesian product of multiple spaces as a fixed-length tuple provided by Gymnasium.

Description

The Tuple space represents the cartesian product of a sequence of Space instances. Each sample is a Python tuple where the i-th element is independently drawn from the i-th sub-space. The number and types of sub-spaces are fixed at construction time.

The class also implements Python's typing.Sequence protocol, meaning it supports indexing (space[i]) and length (len(space)).

The space is numpy-flattenable (is_np_flattenable returns True) only if all constituent sub-spaces are flattenable. When flattenable, the flatten utility concatenates the flattened sub-space samples into a single 1D array. When not flattenable (e.g., contains a Graph or Sequence sub-space), flatten returns a tuple of individually flattened sub-samples.

Usage

Use Tuple when the observation or action consists of a fixed collection of heterogeneous components that should be sampled together. For example, an environment that returns both a continuous observation (Box) and a discrete status flag (Discrete) can use Tuple((Box(...), Discrete(...))).

Code Reference

Source Location

Signature

class Tuple(Space[tuple[Any, ...]], typing.Sequence[Any]):
    def __init__(
        self,
        spaces: Iterable[Space[Any]],
        seed: int | typing.Sequence[int] | np.random.Generator | None = None,
    )

Import

from gymnasium.spaces import Tuple

I/O Contract

Inputs

Name Type Required Description
spaces Iterable[Space] Yes The sequence of sub-spaces forming the cartesian product. Each element must be a Space instance.
seed int, Sequence[int], np.random.Generator, or None No Optional seed. An int seeds the Tuple space which then generates sub-seeds. A list/tuple of ints must match the number of sub-spaces and seeds each one directly.

Outputs

Name Type Description
sample() returns tuple[Any, ...] A tuple where each element is an independent sample from the corresponding sub-space.
contains() returns bool Whether a given value is a tuple of the correct length where each element is contained in the corresponding sub-space.

Key Methods

Method Description
sample(mask=None, probability=None) Generate a random tuple by independently sampling each sub-space. Mask/probability must be a tuple matching the number of sub-spaces.
contains(x) Check that x is a tuple (or list/ndarray promoted to tuple) with the correct length and each element belongs to its sub-space.
seed(seed) Seed the PRNG. Accepts None (random), int (generates sub-seeds), or a list/tuple of ints (one per sub-space).
__getitem__(index) Access a sub-space by index.
__len__() Returns the number of sub-spaces.
to_jsonable(sample_n) Convert a batch of tuple samples to JSON-serializable format. Each sub-space serializes its own components.
from_jsonable(sample_n) Convert JSON-serializable data back to a list of tuples.

Usage Examples

from gymnasium.spaces import Tuple, Box, Discrete
import numpy as np

# Observation: continuous position + discrete mode
space = Tuple((Box(-1, 1, shape=(2,)), Discrete(3)), seed=42)
sample = space.sample()
print(sample)
# e.g. (array([-0.39, 0.21], dtype=float32), np.int64(2))

# Access sub-spaces
print(space[0])     # Box(-1.0, 1.0, (2,), float32)
print(space[1])     # Discrete(3)
print(len(space))   # 2

# Masked sampling
mask = (
    None,                                    # no mask for Box
    np.array([1, 0, 1], dtype=np.int8),      # mask for Discrete (only 0 or 2)
)
masked = space.sample(mask=mask)
print(masked[1])  # 0 or 2

# Seeding with per-subspace seeds
space.seed([42, 123])
s1 = space.sample()
space.seed([42, 123])
s2 = space.sample()
# s1 and s2 are identical

# Membership check
valid = (np.array([0.5, -0.5], dtype=np.float32), np.int64(1))
print(valid in space)  # True

invalid = (np.array([0.5, -0.5], dtype=np.float32), np.int64(5))
print(invalid in space)  # False (5 not in Discrete(3))

# Nested Tuple spaces
nested = Tuple((
    Tuple((Discrete(2), Discrete(3))),
    Box(0, 1, shape=(4,))
))
nested_sample = nested.sample()
print(type(nested_sample))       # <class 'tuple'>
print(type(nested_sample[0]))    # <class 'tuple'>

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment