CS51A - Spring 2025 - Class 7

Example code in this lecture

   more-lists.py
   movies.py

Lecture notes

  • admin
       - how did assignment 2 finish up?
       - lab today/tomorrow

  • lists are mutable
       - what does that mean?
          - we can change (or mutate) the values in a list
       
       - notice that many of the methods that we call on lists change the list itself

       - we can mutate lists with methods, but we can also change particular indices
       
          >>> my_list = [15, 2, 1, 20, 5]
          >>> my_list
          [15, 2, 1, 20, 5]
          >>> my_list[2] = 100
          >>> my_list
          [15, 2, 100, 20, 5]

  • Alternate ways of iterating over lists
       - Write a function called multiply_lists that takes two lists of numbers and creates a new list with the values pairwise multiplied, e.g.

          >>> list1 = [1, 2, 1, 2]
          >>> list2 = [1, 2, 3, 4]
          >>> multiply_lists(list1, list2)
          [1, 4, 3, 8]

       - In words, what would we like to do?
          - Go through the lists at the same time
          - Multiply each element together
          - Append onto a new list

       - How do we go through the lists at the same time?
       - Hint: Here's another way we can iterate through a list

          for item in list:
             print item

          is equivalent to:

          for i in range(len(list)):
             print(list[i])

          - in the second example we're iterating of the indices from 0 up to the length of the list - 1 and then indexing into the lists

       - Look at multiply_lists function in more-lists.py code
          - What does the if statement check?
             - make sure they're the same length
          - the for loop then iterates over the indices and multiplies the corresponding ones

  • sequences
       - lists are part of a general category of data structures called sequences that represent a sequence of things
       - *all* sequences support a number of shared behavior
          - the ability to index using []
          - the ability to slice using [:]
          - a number of built-in functions:
             - len
             - max
             - min
          - the ability to iterate over in with a for loop
       - We've actually seen one other sequence?
          - strings!


  • strings as sequences
       - notice that we can do all the sequence-like things with strings
          >>> s = "banana"
          >>> s[4]
          'n'
          >>> s[2:5]
          'nan'
          >>> len(s)
          6
          >>> for letter in s:
          ... print letter

          b
          a
          n
          a
          n
          a
       - strings, however, are immutable
          >>> s[4] = "c"
          Traceback (most recent call last):
           File "<string>", line 1, in <fragment>
          TypeError: 'str' object does not support item assignment

          - no matter how hard you try, you cannot mutate a string

  • What does the list_to_string function do in more-lists.py code?
       - takes as input a list
          - what is the type of the list?
             - a list of almost anything!
             - anything that we can call str() on (which turns out to be lots of things)
       - concatenates all the items in the list into a single string
          - results starts out as the empty string
          - it iterates through each item in the list and concatenates them on to the results
       - this is similar to our example before of summing up all the numbers in a list

  • tuples (immutable lists): a third sequence
       - For a variety of reasons (we'll get into some eventually), we also have immutable lists, called tuples
       - tuples can be created as literals using parenthesis (instead of square braces)
          >>> my_tuple = (1, 2, 3, 4)
          >>> my_tuple
          (1, 2, 3, 4)
          >>> another_tuple = ("a", "b", "c", "d")
          >>> another_tuple
          ('a', 'b', 'c', 'd')

          - notice that when they print out they also show using parenthesis
       - tuples are sequences and support all the functionality that sequences have:
          >>> my_tuple[0]
          1
          >>> my_tuple[3]
          4
          >>> for val in my_tuple:
          ...    print(val)
          ...
          1
          2
          3
          4
          >>> my_tuple[1:3]
          (2, 3)
       - tuples are immutable!
          >>> my_tuple[0] = 1
          Traceback (most recent call last):
           File "<string>", line 1, in <fragment>
          TypeError: 'tuple' object does not support item assignment
          >>> my_tuple.append(1)
          Traceback (most recent call last):
           File "<string>", line 1, in <fragment>
          AttributeError: 'tuple' object has no attribute 'append'

  • unpacking a tuple
       - if we know how many items are in a tuple we can "unpack" it into individual variables
          
       >>> my_tuple = (1, 2, 3)
       >>> my_tuple
       (1, 2, 3)
       >>> (x, y, z) = my_tuple
       >>> x
       1
       >>> y
       2
       >>> z
       3

       - we can also use this feature to assign to multiple variables in one statement:

       >>> (x, y, z) = (10, 11, 12)
       >>> x
       10
       >>> y
       11
       >>> z
       12
       >>> x, y, z = 10, 11, 12
       >>> x, y, z = "apple", "banana", "pineapple"
       >>> x
       'apple'
       >>> y
       'banana'
       >>> z
       'pineapple'

       notice that we can actually leave off the parenthesis and it still does the right thing

  • tuples are useful for representing data with fixed entries
       - look at the movie_scores variable declaration in movies.py code
          - a list of tuples (specifically, pairs)
             - remember, we can store any value in a list, including tuples
       
  • write a function called print_movies that takes in the a list of tuples (like movie_scores) and prints each movie followed by its score, one movie per line

  • look at the print_movies function in movies.py code
       - iterates over the list, just like any other list
       - movie_pair is a tuple (each entry in the list is a tuple)
          - we unpack the tuple to get at the two values in the tuple
             - we also could have written
                
                movie_pair[0]
                movie_pair[1]

                (see print_movies2) though I think using unpacking is much cleaner
       - once we have the two values, we can print them out
          - \t is a special character that represents a tab (like \n, which represents the end of line character)

  • look at the print_movies3 function in movies.py code
       - we can unpack the two values of the tuple *in* the for loop
       - any of the variants is fine for this class

  • what does the get_movie_score function do in movies.py code
       - takes two parameters, a movie title and the movie information
       - iterates through the movies and tries to find the matching title
          - if it finds it, it returns the score
          - if it doesn't find it, it will iterate through all of the movie entries, finish the for loop and return -1

  • write a function called my_max that takes a list of positive numbers in and returns the largest one
       def my_max(numbers):
          max = -1

          for num in numbers:
             if num > max:
                max = num

          return max

       - key idea: have a variable that keeps track of the largest number seen so far
          - at each iteration, compare the current number to max, if it's bigger, update the max value
       - why initialize it to -1?
          - need to initialize it to something that is smaller than any of the values
          - could also have done something like max = numbers[0] (assuming that the input would have at least one value)

  • look at the get_hightest_rated_movie function in movies.py code
       - very similar idea to my_max function
          - we're finding the largest score
          - also keep track of the movie with the highest score so that we can return that at the end

  • write a function called get_movies_above_threshold that takes as input a the movie scores and a score threshold and returns all of the movies above that threshold
       - Hint: it should look a lot like some of the other examples that we've seen that build up a list of answers (e.g. string_to_list in more-lists.py code)

  • look at get_movies_above_threshold function in movies.py code
       - start out with an empty list
       - iterate through the movie collection
       - check each movie score
          - if the score greater than or equal to the threshold, append it to the end of our list of movies that are above the threshold