Understanding Lists in Python

In almost all programming languages, there is a data structure called Arrays—but wait! Python is different.

Python does not provide a built-in array data structure out of the box. While you can use NumPy, which offers an array-like data structure, today, we will discuss something that is built into Python: Lists.

Lists vs. Arrays

Lists in Python provide many of the same properties as arrays, including:

  1. Appending an element to an existing list
  2. Removing an element from a list
  3. Accessing an element by its index

Defining a List in Python

A list in Python is typically defined as follows:

my_list = ["apple", "banana", "orange"]

This is similar to arrays in other object-oriented programming (OOP) languages. I used a list of strings to make the concept easier to grasp.

Adding Elements to a List

To add a new value to the list, we use the append() method:

my_list.append("grapes")

# Updated list:
# my_list = ["apple", "banana", "orange", "grapes"]

Accessing Elements in a List

Lists in Python are zero-indexed, meaning the first element is at index 0. To fetch "banana", we use the following code:

my_list[1]

# Output: "banana"

Lists Are Dynamic

One key difference between lists in Python and arrays in other languages is that we do not need to specify the initial size of the list. We simply create a list with as many values as we need and can add or remove elements without worrying about its size.

What Is the Size of my_list?

Python automatically manages the list size internally.

How Lists Are Stored in Memory

Let’s break this down step by step:

  • A list is a continuous sequence of values, but that is not how it is stored in memory.
  • When a list is created, its values are stored at available memory locations (which may be scattered across the memory heap). However, Python stores a continuous sequence of memory addresses pointing to these values.
  • The list also keeps track of its length, allowing Python to logically manage memory allocation.

Buffer Space and Performance

Python lists include a buffer of extra space to allow fast insertions. This is why appending elements to a list is an O(1) operation in most cases.

For example

  1. If you request a list of size N, Python may allocate memory for M elements, where M > N.
  2. You can keep adding elements without worrying about memory until N == M.
  3. When M is exceeded, Python creates a new copy of the list with a larger allocated size (K > M).

Some might argue that keeping extra space is wasteful, but this is the trade-off for faster operations. Also, Python’s garbage collector handles unused memory efficiently.

A Quick Look at Tuples

Since lists and tuples are often discussed together, let's briefly cover tuples.

  • Tuples are immutable, meaning their memory cannot be expanded.
  • When you update a tuple, Python creates a new copy instead of modifying the existing one.
  • Tuples are cached by Python for faster retrieval.
  • They are ideal for scenarios where you do not expect future modifications.

Up Next
    Ebook Download
    View all
    Learn
    View all