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.

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.

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.

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() versus raw_input() and using the input function. For numeric fields, verify whether input is a number before saving it.
Now call the functions with two sample US employee leave requests:
add_leave_request(
"Sarah Miller",
"2026-07-20",
"2026-07-24"
)
add_leave_request(
"James Carter",
"2026-08-03",
"2026-08-03"
)
list_leave_requests()
approve_leave_request(1)
list_leave_requests()
Output:
Added leave request for Sarah Miller: 5 day(s)
Added leave request for James Carter: 1 day(s)
1: Sarah Miller | 2026-07-20 to 2026-07-24 | 5 day(s) | Pending
2: James Carter | 2026-08-03 to 2026-08-03 | 1 day(s) | Pending
Request 1 approved.
1: Sarah Miller | 2026-07-20 to 2026-07-24 | 5 day(s) | Approved
2: James Carter | 2026-08-03 to 2026-08-03 | 1 day(s) | Pending
The database now keeps each record after the app closes. In a production HR application, you would also exclude weekends and company holidays when calculating PTO duration.
Things to Keep in Mind
- Lists are your default choice: Use them for most Python projects, especially when storing mixed data such as employee names, dates, and statuses.
- Use list comprehensions for 2D arrays: Do not multiply a list containing inner lists. That approach creates shared references and causes the aliasing bug.
- Validate the requested size: Reject negative or invalid sizes before creating an array from user input.
- Use array.array only for numeric data: It requires one consistent numeric type, so it cannot store employee names or approval notes.
- Install NumPy only when necessary: Standard lists handle small business applications well. NumPy makes more sense for large numerical calculations.
- Move permanent records into a database: Arrays organize data while your script runs, but SQLite preserves records after the program closes.
Frequently Asked Questions
Is a Python list the same thing as an array?
For most everyday purposes, yes. A list is Python’s flexible, general-purpose sequence container and handles basic array tasks. Use array.array or NumPy when you need strict numeric types or better numerical performance.
When should I use array.array instead of a list?
Choose array.array when every value uses the same numeric type and memory efficiency matters. A regular list stays simpler for text, mixed values, and most small applications.
Why did all my rows change when I edited one row?
This happens because of aliasing when you build a 2D array with [[0] * cols] * rows. That expression repeats a reference to one inner list. Use [[0] * cols for _ in range(rows)] instead.
Do I need to install NumPy?
Yes. NumPy is a third-party library, so install it with pip install numpy before importing it. Regular lists and array.array come with Python.
Can I convert between lists, arrays, and NumPy arrays?
Yes. You can create an array.array from a list or pass a list to numpy.array(). NumPy’s .tolist() method converts a NumPy array back into a standard Python list.
What is the fastest way to reset a list to empty?
Call .clear() to remove every item while keeping the same list object. This guide on clearing a list in Python explains the method in detail.
Initializing an array in Python comes down to choosing the right container, whether that means an empty list, independent 2D rows, or a NumPy array. For most projects like this leave request app, start with a plain list and use list comprehensions when you need calculated values or independent rows. I hope you found this article helpful.
You May Also Like
- How to Check the Length of an Array in Python
- How to Convert a String to an Array in Python
- How to Read a File Into an Array in Python
- How to Write an Array to a File in Python
- Comparing Lists, Tuples, Sets, and Dictionaries in Python

Bijay Kumar is an experienced Python and AI professional who enjoys helping developers learn modern technologies through practical tutorials and examples. His expertise includes Python development, Machine Learning, Artificial Intelligence, automation, and data analysis using libraries like Pandas, NumPy, TensorFlow, Matplotlib, SciPy, and Scikit-Learn. At PythonGuides.com, he shares in-depth guides designed for both beginners and experienced developers. More about us.