PyTorch
Dataloader
Programming Error
Subscriptable Issue
Debugging

Problem with Dataloader object not subscriptable

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

Introduction

TypeError: 'DataLoader' object is not subscriptable means your code is treating a PyTorch DataLoader like a list, for example with loader[0]. That fails because DataLoader is designed to be an iterable over batches, not a random-access container.

The fix depends on what you actually wanted. If you wanted one batch, use iter and next. If you wanted one sample, index the underlying dataset instead.

Why DataLoader Does Not Support Indexing

A Dataset and a DataLoader have different jobs:

  • 'Dataset knows how to return one sample'
  • 'DataLoader knows how to batch, shuffle, and iterate over samples'

That distinction is why this works:

python
sample = dataset[0]

but this does not:

python
batch = loader[0]

The loader may be shuffling data, using multiple workers, pinning memory, or reading from an IterableDataset, so random-access subscription is not part of its contract.

The Normal Way: Iterate Over the Loader

For training and evaluation, use a loop:

python
1import torch
2from torch.utils.data import DataLoader, TensorDataset
3
4X = torch.randn(10, 3)
5y = torch.randint(0, 2, (10,))
6
7dataset = TensorDataset(X, y)
8loader = DataLoader(dataset, batch_size=4, shuffle=True)
9
10for batch_x, batch_y in loader:
11    print(batch_x.shape, batch_y.shape)

That is the intended usage. Each iteration yields one batch.

If You Want Only One Batch

Sometimes you are just inspecting data in a notebook and want the first batch. In that case:

python
batch_x, batch_y = next(iter(loader))
print(batch_x.shape)
print(batch_y.shape)

This is the right mental model:

  • 'iter(loader) creates a batch iterator'
  • 'next(...) pulls one batch from that iterator'

It is the closest equivalent to loader[0], but it respects the iterable design.

If You Want One Sample

If the code really wants a single sample rather than a batch, index the dataset:

python
sample_x, sample_y = dataset[0]
print(sample_x.shape)
print(sample_y)

That keeps responsibilities clean. The dataset answers sample-level access; the loader answers batch-level iteration.

This is especially important if you later change batch size or turn on shuffling. A dataset sample and a loader batch are different concepts.

A Common Helper-Function Bug

This error often appears because a helper function expects a dataset but receives a loader by mistake:

python
1def preview_first_item(data):
2    return data[0]
3
4preview_first_item(loader)   # wrong
5preview_first_item(dataset)  # fine

A safer version makes the expectation explicit:

python
def preview_first_batch(loader):
    return next(iter(loader))

Small naming differences like dataset versus loader prevent a lot of confusion in larger training codebases.

IterableDataset Makes Indexing Even Less Appropriate

Some datasets are not indexable at all. IterableDataset is meant for streaming data where samples are produced sequentially:

python
1from torch.utils.data import IterableDataset, DataLoader
2
3class RangeStream(IterableDataset):
4    def __iter__(self):
5        for i in range(5):
6            yield i
7
8loader = DataLoader(RangeStream(), batch_size=2)
9
10for batch in loader:
11    print(batch)

In this case, random access makes no sense, which is another reason PyTorch keeps DataLoader focused on iteration rather than subscription.

Avoid list(loader) for Inspection

A common workaround is:

python
batches = list(loader)
print(batches[0])

That works for tiny datasets, but it materializes every batch in memory. For real training jobs, that is wasteful and can be very slow. Prefer next(iter(loader)) when you only need one batch preview.

Common Pitfalls

  • Writing loader[0] because the code mentally treats a loader like a list.
  • Forgetting whether the current variable is a dataset or a loader.
  • Converting the whole loader to a list just to inspect one batch.
  • Expecting a loader to provide stable batch order when shuffle=True.
  • Ignoring the difference between sample-level access and batch-level iteration.

Summary

  • 'DataLoader is iterable, not subscriptable.'
  • Use for ... in loader for normal batch processing.
  • Use next(iter(loader)) when you need one batch quickly.
  • Use dataset[index] when you need one specific sample.
  • Keep dataset and loader responsibilities separate to avoid this error entirely.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

All Rights Reserved.