Skip to main content

How to Initialize List with Default Values in Python

Initializing lists with default values is a fundamental operation in Python, allowing developers to pre-allocate memory or set up data structures for later use. Whether you need a simple list of zeros, a sequence of numbers, or a complex grid (matrix), choosing the right initialization method is crucial for performance and bug prevention.

This guide explores the standard multiplication technique, list comprehensions, and how to avoid the common "mutable reference" trap when creating multi-dimensional lists.

Method 1: Using the Multiplication Operator *

The most concise way to initialize a list with immutable values (like integers, floats, strings, or None) is using the multiplication operator.

Syntax:

[value] * count

Example:

# Initialize a list of 5 zeros
zeros = [0] * 5
print(f"Zeros: {zeros}")

# Initialize a list of strings
strings = ["empty"] * 3
print(f"Strings: {strings}")

# Initialize with None (common for placeholders)
placeholders = [None] * 4
print(f"Placeholders: {placeholders}")

Output:

Zeros: [0, 0, 0, 0, 0]
Strings: ['empty', 'empty', 'empty']
Placeholders: [None, None, None, None]
note

This method is efficient and safe for immutable types. Be careful when using it with mutable types like lists or dictionaries (see Method 3).

List comprehensions provide a flexible way to initialize lists. They are particularly useful when the initial values need to be calculated dynamically or when creating lists of mutable objects to ensure each element is unique in memory.

Syntax:

[expression for _ in range(count)]

Example:

# Initialize a sequence of squares
squares = [x**2 for x in range(5)]
print(f"Squares: {squares}")

# Initialize distinct dictionary objects
# Each iteration creates a NEW dictionary instance
dicts = [{"id": i} for i in range(3)]
print(f"Dictionaries: {dicts}")

Output:

Squares: [0, 1, 4, 9, 16]
Dictionaries: [{'id': 0}, {'id': 1}, {'id': 2}]

Method 3: The Common Pitfall (Multi-dimensional Lists)

A classic bug in Python occurs when initializing a list of lists (a matrix) using the multiplication operator. This creates shallow copies, meaning all sub-lists point to the exact same object in memory.

Example of Problem

# ⛔️ Incorrect: Creating a 3x3 grid using multiplication
# This creates 3 references to the SAME list object
grid_bad = [[0] * 3] * 3

print("Initial Bad Grid:")
print(grid_bad)

# Modifying ONE element affects ALL rows
grid_bad[0][0] = 99
print("\nAfter Modifying [0][0]:")
print(grid_bad)

Output:

Initial Bad Grid:
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]

After Modifying [0][0]:
[[99, 0, 0], [99, 0, 0], [99, 0, 0]]

Solution

Use a list comprehension. This forces Python to execute the inner list creation logic [0] * 3 freshly for every row, creating independent objects.

# ✅ Correct: Creating a 3x3 grid using comprehension
grid_good = [[0] * 3 for _ in range(3)]

# Modifying one element works as expected
grid_good[0][0] = 99
print("Correct Grid Modification:")
print(grid_good)

Output:

Correct Grid Modification:
[[99, 0, 0], [0, 0, 0], [0, 0, 0]]

Method 4: Using itertools and Generators

For very large lists where memory efficiency is a concern, or for functional programming styles, you can use iterators.

Using itertools.repeat

This creates an iterator that yields the same value repeatedly. It is memory efficient because it doesn't store the list in memory until you explicitly convert it.

import itertools

# Create an iterator (not a list yet)
iterator = itertools.repeat("A", 3)

# Convert to list
repeat_list = list(iterator)
print(f"Repeat List: {repeat_list}")

Output:

Repeat List: ['A', 'A', 'A']

Using Generator Expressions

If you only need to iterate over the default values once (e.g., passing them to a function), use a generator expression instead of a list comprehension to save memory.

# Generator expression (note the parentheses)
gen = (x * 10 for x in range(5))

print("Iterating generator:")
for val in gen:
print(val, end=" ")

Output:

Iterating generator:
0 10 20 30 40

Conclusion

To initialize lists efficiently in Python:

  1. Use [value] * n for immutable types like integers, floats, strings, and None.
  2. Use [... for _ in range(n)] for mutable types (lists, dicts) to avoid shared reference bugs.
  3. Use Generators if you are dealing with massive sequences and don't need to store everything in memory at once.