TensorFlow
Python
Machine Learning
Data Manipulation
Programming Tutorial

Making a list and appending to it in TensorFlow

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

Making a list in TensorFlow depends on where your code runs. In eager execution, ordinary Python lists work fine because operations execute immediately. Inside tf.function or graph-style loops, however, Python list appends usually do not behave the way people expect. In that case, TensorArray is the right TensorFlow-native structure.

Eager Mode: Use Plain Python Lists

In modern TensorFlow, eager execution is enabled by default. If you are building up values in ordinary Python code before converting them into a tensor, just use a normal list.

python
1import tensorflow as tf
2
3values = []
4for i in range(5):
5    values.append(i * 2)
6
7tensor = tf.constant(values)
8print(tensor)

This is simple, readable, and perfectly valid when the loop itself is Python-driven.

The important point is that the list is a Python container, not a TensorFlow data structure. That is fine as long as the logic is running eagerly and you do not need TensorFlow to trace the append behavior into a graph.

Why Python Appends Break Inside tf.function

When you decorate a function with tf.function, TensorFlow traces Python code to build a graph. A Python list append is a side effect on a Python object, not a TensorFlow op. That means it may happen only during tracing or behave differently from what you expect on repeated calls.

This kind of code is therefore misleading:

python
1import tensorflow as tf
2
3items = []
4
5@tf.function
6def bad_append(x):
7    items.append(x)
8    return x * 2

Even if it seems to run once, it is not the right model for graph-compatible accumulation.

Use TensorArray for Graph-Safe Appends

TensorArray is designed for building a sequence of tensors across loop iterations in graph mode.

python
1import tensorflow as tf
2
3@tf.function
4def build_values(n):
5    ta = tf.TensorArray(dtype=tf.int32, size=0, dynamic_size=True)
6
7    for i in tf.range(n):
8        ta = ta.write(i, i * i)
9
10    return ta.stack()
11
12print(build_values(5))

This is the TensorFlow equivalent of appending items and then turning the result into one tensor. dynamic_size=True allows the structure to grow, which matches the mental model of appending.

A TensorArray is especially useful in loops, sequence models, and custom training logic where each iteration produces a tensor you want to collect.

Another Option: Accumulate Then Concatenate

If each step produces tensors with compatible shapes, you can also collect them and concatenate later. In eager mode this can be fine, but repeated tf.concat inside a loop is usually less efficient than writing once into a TensorArray.

python
1import tensorflow as tf
2
3parts = []
4for i in range(3):
5    parts.append(tf.constant([i, i + 1]))
6
7result = tf.concat(parts, axis=0)
8print(result)

This is a good pattern for short eager-mode workflows, but inside traced graph code TensorArray is usually clearer and more scalable.

Choosing the Right Tool

Use a Python list when:

  • your code runs eagerly
  • you are just preparing values before tensor conversion
  • you do not need TensorFlow to trace the append behavior

Use TensorArray when:

  • the accumulation happens inside tf.function
  • the data is produced inside TensorFlow loops
  • you want graph-friendly, TensorFlow-managed sequence building

If the final result is ragged or variable-length in a more complex way, you may also need tf.RaggedTensor, but that solves a different problem from simple append behavior.

Common Pitfalls

The most common mistake is treating Python list mutation as if TensorFlow will automatically capture it in a graph. It usually will not behave the way you intend inside tf.function.

Another mistake is using repeated tf.concat inside a long loop. That works functionally, but it is often inefficient compared with TensorArray.

Developers also sometimes confuse Python containers with tensors. A list of tensors is not itself a tensor until you stack or concatenate it.

Finally, be careful about shapes and dtypes. TensorArray expects a consistent tensor type across writes unless you are intentionally handling more advanced cases.

Summary

  • In eager mode, plain Python lists and append usually work fine.
  • Inside tf.function, use tf.TensorArray for graph-safe accumulation.
  • 'TensorArray.write plus stack is the TensorFlow equivalent of append then collect.'
  • Repeated tf.concat in loops is usually less efficient than TensorArray.
  • Choose the container based on whether the logic is Python-driven or graph-traced.

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.