How to Initialize an Array in Python?

A few months back, I built a local app to track paid time off for my 10-person team. HR managed everything in Excel, and someone often missed an update or approved overlapping dates. I opened a Python file and considered how to store employees, PTO balances, and approval statuses.

That is where I had to stop and ask a basic question: how do I even initialize an array in Python to hold this data? It sounds simple, but Python offers several ways to do it, and picking the wrong one creates bugs that are hard to spot later. I learned this while building a weekly schedule grid where every row ended up pointing to the same data.

You will learn seven practical ways to initialize an array in Python, then save sample leave records in SQLite.

What Counts as an Array in Python?

Python does not use a built-in array type as its default sequence like C or Java. Its everyday container for ordered, changeable data is the list, which can hold mixed data types and change size at runtime. All examples use Python 3.11 or later on a local Windows, macOS, or Linux machine.

For most beginner and intermediate projects, a list is exactly what people mean when they say “array.” This guide on creating arrays in Python covers more on building these containers.

Python also ships a stricter option called array.array, which only stores one fixed numeric type and uses less memory than a list. For heavier numeric work, developers reach for NumPy, a third-party library built for fast array operations, detailed in this NumPy array guide.

In our leave app, employee names and approval notes fit naturally into a list. PTO day counts, always whole numbers, suit array.array. NumPy would suit statistics across hundreds of employees.

Method 1: Initialize an Array in Python as an Empty List

The simplest way to initialize an array in Python is to start with an empty list and add items later. This works well when you do not know the final size ahead of time, which matches how leave requests arrive throughout the year.

pto_requests = []
print(pto_requests)

Output:

[]

You can refer to the screenshot below to see the output.

Initialize an Array in Python

Add requests with .append() as employees submit them, following this guide to add elements to an empty list. You can then find the length of a list or check whether an array is empty.

Method 2: Initializing With Repeated Default Values

Sometimes you already know how many items you need. For our team of 10, I wanted a quick way to set default approval flags before requests came in. Multiplying a single-item list by the employee count does this in one line.

approval_flags = [False] * 10
print(approval_flags)

Output:

[False, False, False, False, False, False, False, False, False, False]

You can refer to the screenshot below to see the output.

How to Initialize an Array in Python

This approach is fast and readable, but it only works safely with immutable values like numbers, strings, and booleans. An immutable value cannot change in place, so each slot stays independent. This matters a lot once we get to 2D arrays.

Method 3: Initialize an Array in Python With List Comprehension

A list comprehension builds a list by looping and applying an expression in one line. It gives more control than simple multiplication because you can calculate each value, not just repeat one.

Here is one that assigns a starting PTO balance based on years of service.

years_employed = [1, 2, 3, 1, 5, 2, 4, 1, 3, 2]
pto_balances = [10 + (year * 2) for year in years_employed]
print(pto_balances)

Output:

[12, 14, 16, 12, 20, 14, 18, 12, 16, 14]

You can refer to the screenshot below to see the output.

Initialize an Python Array

Pro Tip: I reach for a list comprehension when my initialization needs a calculation, not just a repeated value. It keeps the code on one readable line instead of using a longer loop with an append call.

Method 4: Generating Values With range()

The built-in range() function produces a sequence of numbers with a start, stop, and optional step. Wrapping it in list() turns that sequence into an actual list. This works well for sequential data such as employee ID numbers.

employee_ids = list(range(101, 111))
print(employee_ids)

Output:

[101, 102, 103, 104, 105, 106, 107, 108, 109, 110]

You can also use range() with a step value to build a countdown of remaining PTO days.

remaining_pto_countdown = list(range(15, 0, -3))
print(remaining_pto_countdown)

Output:

[15, 12, 9, 6, 3]

Method 5: Building 2D Arrays With Independent Rows

A 2D array is a list of lists, where each inner list represents a row. For the leave app, I wanted a weekly schedule grid with 10 employees and five weekdays. Each value tracks whether an employee booked that day off.

Build this grid with a list comprehension that creates a new inner list for every employee.

weekly_schedule = [[0] * 5 for _ in range(10)]
weekly_schedule[0][0] = 1

print(weekly_schedule[0])
print(weekly_schedule[1])

Output:

[1, 0, 0, 0, 0]
[0, 0, 0, 0, 0]

Changing employee 0’s Monday value did not affect employee 1’s row. Each row occupies a separate list in memory.

This method is explored further in this guide on initializing a 2D array in Python. You can process the grid with patterns from this article on iterating through a 2D array.

The Aliasing Trap With [0 * cols] * rows

I made this mistake in my first schedule grid. Multiplying a list of lists creates one row and references it 10 times. This behavior is called aliasing, where several positions point to the same object.

broken_schedule = [[0] * 5] * 10
broken_schedule[0][0] = 1

print(broken_schedule[0])
print(broken_schedule[1])

Output:

[1, 0, 0, 0, 0]
[1, 0, 0, 0, 0]

I changed only employee 0’s Monday value, but every row changed. Always use [[0] * 5 for _ in range(10)] when rows must remain independent.

Method 6: Typed Numeric Storage With array.array

When your data is strictly numeric, Python’s built-in array module gives you a more memory-efficient container than a list. Unlike a list, array.array requires a type code. This single character tells Python what kind of number the array will store.

The code 'i', for example, represents signed integers.

import array

pto_days_used = array.array(
'i',
[0, 2, 5, 1, 0, 3, 8, 0, 4, 2]
)

print(pto_days_used)

Output:

array('i', [0, 2, 5, 1, 0, 3, 8, 0, 4, 2])

This works well for tracking how many PTO days each employee has used this year. Because every value must use the same numeric type, array.array catches mistakes that a regular list would allow.

Learn how to convert a list to an array, then check positions by finding an element’s index.

Method 7: NumPy zeros() and full()

For heavier numeric work, NumPy provides fast array operations outside Python’s core toolkit. Install it once from your terminal:

pip install numpy

Output:

Successfully installed numpy

The exact installation message and version number can differ on your machine.

The zeros() function creates an array filled with zeros. This works well for a fresh approval matrix before managers make any decisions.

import numpy as np

approval_matrix = np.zeros((10, 3))
print(approval_matrix)

Output:

[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]

This guide on NumPy zeros covers more shape options. If you need a starting value other than zero, full() fills every slot with your chosen number.

leave_grid = np.full((10, 3), 0)
print(leave_grid)

Output:

[[0 0 0]
[0 0 0]
[0 0 0]
[0 0 0]
[0 0 0]
[0 0 0]
[0 0 0]
[0 0 0]
[0 0 0]
[0 0 0]]

NumPy avoids the aliasing trap because zeros() and full() allocate independent storage for each row. For an uninitialized array built for speed, check this guide on NumPy empty arrays.

You can also create grids with NumPy 2D arrays, follow the correct process for copying a NumPy array, or learn about converting a NumPy array to a list.

Putting It Into Practice: Saving Leave Requests to SQLite

Lists and arrays disappear once you close the program. For a real leave request app, I moved the data into a local SQLite database. A database stores organized records so the application can retrieve them later.

Python’s built-in sqlite3 module manages SQLite files without a separate database server. This makes SQLite a practical choice for a beginner Python project running on one local machine.

The project stayed simple:

leave_app/
├── app.py
└── leave_requests.db

The app.py file contains the application code. Python creates leave_requests.db when the script first connects to the database.

I used the datetime module to parse dates and calculate how many calendar days each request covers.

import sqlite3
from datetime import datetime

conn = sqlite3.connect("leave_requests.db")
cursor = conn.cursor()

cursor.execute("""
CREATE TABLE IF NOT EXISTS leave_requests (
id INTEGER PRIMARY KEY AUTOINCREMENT,
employee_name TEXT NOT NULL,
start_date TEXT NOT NULL,
end_date TEXT NOT NULL,
duration_days INTEGER NOT NULL,
approved INTEGER DEFAULT 0
)
""")

print("Leave request table ready.")

Output:

Leave request table ready.

The CREATE TABLE statement creates a structure for storing each leave request. The IF NOT EXISTS condition prevents an error when you run the script again.

A function is a named block of reusable code that performs one job. Each function below adds, displays, or approves a request.

This pattern follows the same principles covered in this guide on defining a function in Python. As the project grows, you can call a function from another file.

def calculate_duration(start_date, end_date):
start = datetime.strptime(start_date, "%Y-%m-%d")
end = datetime.strptime(end_date, "%Y-%m-%d")
return (end - start).days + 1


def add_leave_request(employee_name, start_date, end_date):
duration = calculate_duration(start_date, end_date)

cursor.execute(
"""
INSERT INTO leave_requests
(employee_name, start_date, end_date, duration_days)
VALUES (?, ?, ?, ?)
""",
(employee_name, start_date, end_date, duration)
)

conn.commit()
print(
f"Added leave request for {employee_name}: "
f"{duration} day(s)"
)


def list_leave_requests():
cursor.execute("""
SELECT id, employee_name, start_date,
end_date, duration_days, approved
FROM leave_requests
""")

for row in cursor.fetchall():
status = "Approved" if row[5] == 1 else "Pending"
print(
f"{row[0]}: {row[1]} | "
f"{row[2]} to {row[3]} | "
f"{row[4]} day(s) | {status}"
)


def approve_leave_request(request_id):
cursor.execute(
"UPDATE leave_requests SET approved = 1 WHERE id = ?",
(request_id,)
)

conn.commit()
print(f"Request {request_id} approved.")


print("Leave request functions ready.")

Output:

Leave request functions ready.

To collect data, I used the built-in input() function. It always returns a string, so validate dates before using them.

start_date = input("Enter start date (YYYY-MM-DD): ")
print(f"Start date entered: {start_date}")

Output:

Enter start date (YYYY-MM-DD): 2026-07-20
Start date entered: 2026-07-20

For more details, see input() ve