class

ModuleList

extendsModule
ModuleList(modules: list[Module] | None = None)
source

A list-like container that registers all child modules with the parent.

ModuleList stores an ordered collection of Module objects and makes them visible to the Lucid module system (parameters(), state_dict(), device transfer, etc.) exactly like named sub-modules defined as class attributes. Unlike Sequential, it does not define forward — the user iterates over the list manually and controls the data flow.

Parameters

moduleslist[Module] or None= None
Initial list of modules to register. Each module is stored under its integer index converted to a string key ('0', '1', …). Pass None (default) to start with an empty list.

Attributes

_modulesOrderedDict[str, Module | None]
Internal ordered mapping from string index to child module.

Notes

  • forward is intentionally not implemented — calling it raises NotImplementedError. Design your own data flow in the enclosing module's forward method.
  • Parameters of all registered modules participate in gradient computation and are returned by parameters() and named_parameters() on the parent module.
  • After insertion or deletion the internal indices are kept contiguous by _renumber_modules.

Examples

**Ensemble of encoders — manual iteration:**
>>> import lucid
>>> import lucid.nn as nn
>>>
>>> class EnsembleEncoder(nn.Module):
...     def __init__(self, n: int, in_dim: int, out_dim: int) -> None:
...         super().__init__()
...         self.encoders = nn.ModuleList(
...             [nn.Linear(in_dim, out_dim) for _ in range(n)]
...         )
...
...     def forward(self, x: lucid.Tensor) -> lucid.Tensor:
...         # Stack outputs from each encoder along a new axis
...         outputs = [enc(x) for enc in self.encoders]
...         return lucid.stack(outputs, dim=0)
>>>
>>> enc = EnsembleEncoder(n=4, in_dim=256, out_dim=64)
**Dynamic layer collection built incrementally:**
>>> class DynamicMLP(nn.Module):
...     def __init__(self, dims: list[int]) -> None:
...         super().__init__()
...         self.layers = nn.ModuleList()
...         for in_d, out_d in zip(dims[:-1], dims[1:]):
...             self.layers.append(nn.Linear(in_d, out_d))
...
...     def forward(self, x: lucid.Tensor) -> lucid.Tensor:
...         for layer in self.layers[:-1]:
...             x = lucid.nn.functional.relu(layer(x))
...         return self.layers[-1](x)
>>>
>>> mlp = DynamicMLP([784, 512, 256, 10])

Methods (9)

dunder

__init__

None
__init__(modules: list[Module] | None = None)
source

Initialise the ModuleList module. See the class docstring for parameter semantics.

fn

append

None
append(module: Module)
source

Append a module to the end of the ModuleList.

fn

extend

None
extend(modules: Iterable[Module])
source

Append each module from an iterable to the ModuleList.

fn

insert

None
insert(index: int, module: Module)
source

Insert a module at the given position in the ModuleList.

fn

forward

Tensor
forward(args: object = ())
source

Apply the contained modules to the input.

Parameters

None
No description.

Returns

Tensor

Output tensor produced by the contained modules.

dunder

__getitem__

Module
__getitem__(idx: int | slice)
source

Return the child module(s) at the given index or slice.

dunder

__setitem__

None
__setitem__(idx: int, module: Module)
source

Replace the child module at the given index.

dunder

__len__

int
__len__()
source

Return the number of registered child modules.

dunder

__iter__

Iterator[Module]
__iter__()
source

Iterate over the registered child modules.