pt2

Lists

Introduction to Lists

  • Lists allow us to store many values in a named collection.
  • Example: Instead of using multiple variables like grade1, grade2, grade3, we can use a single list called grades.
  • Access individual items in the list using a numeric index:
    • grades[0] to get the first item
    • grades[1] to get the second item
  • Slicing lists and helpful list methods were discussed in previous sessions.

Memory and Variables in Lists

  • Whenever a variable is created, a space in the computer's memory is allocated for that variable.
  • The computer tracks the location in memory, while the variable name is merely a reference and holds no intrinsic meaning.
  • Lists, unlike single variables, require multiple spaces in memory:
    • Memory allocation for lists is dynamic, and the exact size may not be known initially.
    • The .append() method allows us to increase the size of a list incrementally.
    • Note: This dynamic resizing can result in differences and complications compared to static variables.

Reference Variables and Aliasing

  • When a list is created and assigned to a variable (e.g., mylist), what is actually created is a reference to that list:
    • Example: The variable mylist does not contain the actual list data but points to its memory location (similar to a hyperlink).
  • Changes to the list through mylist can affect multiple variables pointing to the same list:
    • This leads to the concept of aliasing, where different variable names refer to the same memory location.
    • Aliasing can lead to unintended side effects when one variable modifies the list, affecting the others.

Copying Lists

  • There are multiple ways to copy a list in Python, each with different implications:

    1. Shallow Assignment:
     list1 = [5, 3, 7, 9, 10]
     list2 = list1  # list2 points to the same list as list1
     list2[1] = 99  # Modifying list2 also affects list1
    
    • Output: Both list1 and list2 will display [5, 99, 7, 9, 10].
    1. Manual Copying:
     list1 = [5, 3, 7, 9, 10]
     list2 = []
     for item in list1:
         list2.append(item)
     list1[1] = 5  # Modifying list1 does not affect list2
    
    • Output: list1 remains [5, 5, 7, 9, 10], and list2 stays [5, 3, 7, 9, 10].
    1. Using Slicing Syntax:
     list1 = [5, 3, 7, 9, 10]
     list2 = list1[:]  # Creates a shallow copy of list1
     list1[1] = 5
    
    • Output: list1 is [5, 5, 7, 9, 10], and list2 remains [5, 3, 7, 9, 10].

Function Parameters and Lists

  • When data is passed to a function as an argument, a copy of the data is created, stored in the parameter, and is kept in a separate memory location.
  • Changes made to this parameter data do not affect the original argument’s data unless they are mutable types (e.g., lists):
    • For lists, only a reference to the original list is passed, allowing modifications within the function to affect the original list:
    • Example:
      python def changeList(my_list): idx = 0 while idx < len(my_list): my_list[idx] += 3
    • Calling changeList(in_list) modifies in_list directly.

Multidimensional Lists

  • Lists can contain entries of any data type, including other lists, making them a powerful tool for creating multidimensional data structures:
    • Example of a 2D list:
      python my2dList = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    • my2dList has a length of 3, with each entry being a list of length 3.
    • Lists can be nested arbitrarily deep, but 2D and 3D lists are the most common use cases.

Indexing and Accessing Multidimensional Lists

  • Accessing elements in a multidimensional list involves chaining multiple indices:
    • Example:
      python my2dList[0] # Returns the first list: [1, 2, 3] my2dList[0][2] # Returns element at [0][2]: 3
  • To traverse a multidimensional list and process each value, nested loops are needed:
    • Example:
      python for mylist in my2dList: for val in mylist: print(val)

Practical Applications of Multidimensional Lists

  • Common use cases for multidimensional lists include:
    • Representing tables of data (e.g., mydata[row#][col#])
    • Grid-based representations (e.g., for board games)
    • Storing pixel data of images
    • Representations of matrices in mathematical contexts.

Representing Matrices with 2D Lists

  • Example of using a 2D list to represent a matrix:
  my_matrix = [[1, 2, 3, 4], [10, 20, 30, 40], [100, 200, 300, 400]]
  • To get a value from the matrix at row r and column c, use:
    python value = my_matrix[r][c]
  • To find the number of rows:
    python num_rows = len(my_matrix)
  • To find the number of columns:
    python num_cols = len(my_matrix[0])
  • Important: Ensure all rows are of equal size; do not use .append() to add rows after initialization. Start by defining an empty structure filled with placeholder values.

Practice Problem with 2D Lists

  • Write a function that takes in two 2D lists and performs matrix multiplication, ensuring the matrices are of compatible sizes for multiplication.

Next Steps

  • Review of concepts discussed today includes:
    • Lists in memory
    • Aliasing
    • Lists in functions
    • Multidimensional lists
  • Next session will cover working with files and their manipulation.