Skip to content

Python offers two primary ways to store a collection of data: arrays and lists. While they may seem similar, they have key differences in how they are implemented, how they behave, and their performance characteristics.


Arrays

Arrays in Python are represented using the array module or more commonly, the numpy library, and they have distinct features:

Key Characteristics:

  1. Fixed Size: The size of an array is fixed in advance. Once created, the number of elements cannot be changed unless the array is resized, which involves creating a new array.

  2. Homogeneous Elements: Arrays only store elements of the same type. This means they are much more memory-efficient than lists, as the data is tightly packed and does not require additional information for each element.

  3. Memory Layout: Arrays are stored in a continuous block of memory. This makes them very efficient for random access, as accessing any element by index takes constant time (O(1)), regardless of the element's position in the array.

  4. Insertion and Deletion: Inserting or deleting elements in the middle of an array is expensive because the elements after the insertion or deletion point need to be shifted to accommodate the new element or close the gap. This takes linear time (O(n)).

  5. Performance:

    • Accessing an element: Accessing an element by index (arr[i]) takes constant time, as arrays provide random access. The time to access any element is the same, whether it's the first or the last element.
    • Insertion/Deletion: Inserting or deleting elements, especially in the middle, requires shifting elements, which results in a linear time complexity (O(n)).

Example of Creating an Array:

python
import array

# Create an array of integers
arr = array.array('i', [1, 2, 3, 4, 5])
print(arr[2])  # Output: 3

# Append an element to the end of the array
arr.append(6)

# Insert an element at a specific position
arr.insert(2, 10)  # Insert 10 at index 2

Lists

Python lists are more flexible and commonly used in Python programming. However, their performance differs significantly from arrays in certain areas.

Key Characteristics:

  1. Dynamic Size: Lists are dynamic, meaning they can grow or shrink in size as needed. This is achieved by allocating extra space in memory when the list is created.

  2. Heterogeneous Elements: Unlike arrays, lists can store elements of different types, including integers, strings, and even other lists. This provides more flexibility, but it comes at the cost of efficiency in memory storage.

  3. Memory Layout: Lists are not stored in a contiguous block of memory like arrays. Instead, they use pointers to the objects stored in memory, which allows for dynamic resizing but results in more overhead.

  4. Performance:

    • Accessing an element: Accessing an element by index (lst[i]) is constant time (O(1)), similar to arrays.
    • Insertion/Deletion: While inserting or deleting at the end of the list is generally constant time (O(1)), inserting or deleting elements at other positions takes linear time (O(n)), as elements need to be shifted.

Example of Creating a List:

python
# Create a list with mixed types
lst = [1, "hello", 3.14, [1, 2, 3]]
print(lst[1])  # Output: hello

# Append an element to the end of the list
lst.append("world")

# Insert an element at a specific position
lst.insert(2, "inserted")

Performance Considerations

When comparing the performance of lists and arrays, it's important to understand their strengths and weaknesses:

1. Access Time:

  • Arrays: Accessing elements is constant time (O(1)), no matter where the element is in the array.
  • Lists: Accessing elements is also constant time (O(1)), as the list maintains a dynamic structure, but it may have additional overhead due to the use of pointers.

2. Insertion/Deletion:

  • Arrays: Inserting or deleting elements in an array, especially in the middle, is expensive. It requires shifting all subsequent elements, which results in linear time complexity (O(n)).
  • Lists: Inserting or deleting elements at the end of a list is constant time (O(1)), but insertion/deletion at other positions takes linear time (O(n)), as elements need to be shifted.

3. Memory Usage:

  • Arrays: More memory-efficient as they store elements of the same type in a contiguous block of memory.
  • Lists: Lists are less memory-efficient because they store pointers to the actual objects, which adds overhead.

When to Use Lists vs. Arrays

  • Use Arrays when:

    • You need efficient memory usage and fast access to elements by index.
    • You are working with numerical data and need to perform mathematical operations.
    • You need a fixed-size collection of elements with a known type (e.g., numerical data).
  • Use Lists when:

    • You need a flexible collection that can store mixed data types.
    • You need dynamic resizing and frequent additions/removals of elements.
    • You are not concerned with the performance of insertion or deletion at arbitrary positions.
FeatureArraysLists
SizeFixed (in most cases)Dynamic (can grow or shrink)
Element TypeHomogeneous (all elements must be of the same type)Heterogeneous (different types allowed)
Memory LayoutContiguous block of memoryPointers to objects in non-contiguous memory
Access TimeO(1) (constant time)O(1) (constant time)
Insertion/DeletionO(n) (linear time)O(1) at the end, O(n) elsewhere
Use CasesNumerical data, fixed-size collectionsMixed data types, dynamic collections

Numpy Arrays for More Complex Operations

While Python's built-in arrays are efficient for basic tasks, for more advanced operations like matrix manipulation or handling large datasets, the numpy library provides a powerful alternative.

Numpy Array Features:
  • Numpy arrays are homogeneous, just like Python arrays, and provide a more compact memory layout and efficient processing.
  • Numpy supports vectorized operations, which allow you to perform operations on entire arrays or matrices without explicit loops.
Example of Creating a Numpy Array:
python
import numpy as np

# Create a 3x3 matrix of zeros
matrix = np.zeros((3, 3))
print(matrix)

# Create a matrix from a nested list
matrix = np.array([[0, 1], [1, 0]])
print(matrix)

# Use arange to generate a range of values
row2 = np.arange(5)  # Output: [0 1 2 3 4]
print(row2)
Matrix Operations in Numpy:

Numpy provides support for matrix operations such as multiplication and addition, which are optimized and more efficient than using nested lists.

python
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])

# Matrix addition
C = A + B
print(C)  # Output: [[ 6  8] [10 12]]

# Matrix multiplication
C = np.dot(A, B)
print(C)  # Output: [[19 22] [43 50]]

Arrays are more useful for representing matrices (to represent graphs) In list notation, these are nested lists [ [0,1], [1,0] ]

python
# list comprehension
zeromatrix = [ [ 0 for i in range(3)]  for j in range(3) ]
	# This is the way of making matrix using lists, no direct way

The Numpy library provides arrays as a basic type

python
Inport numpy as np
zeromatrix = np.zero(shape = (3,3))

# can create an array from any sequence type
newarray = np.array( [ [0,1], [1,0]])

# arange is the equivalent of range for lists
row2 = np.arange(5)

# can operate on a matrix as a whole
	C = 3*A + B
	C = np.matmu(A,B)   # matmu is matrix multiplication

Made with ❤️ for students, by a fellow learner.