== Slicing lists == - we saw that you can slice strings. Works with lists too. subjects = ["Computer Science", "Biology", "French", "History"] print subjects[0:2] print subjects[:1] print subjects[:2] print subjects[2:] == Aliasing == - last week we saw examples where two variables referred to the same object. This is called "aliasing" - Recap: - If the object is mutable, changing what one variable refers to changes what the other one refers to. - If it's not, you can't change it; you can only make a new object that has the changes. So you can't effect what one variable references by changing the other. - New fact: Slicing creates a new object, even if you slice the whole list. subjects = ["Computer Science", "Biology", "French", "History"] subjects_copy = subjects # Both refer to the same list object. subjects subjects_copy subjects[0] = "Commerce" # So changing one changes both. subjects subjects_copy subjects_clone = subjects[:] # A brand new object. subjects # Since they are two different objects, subjects_clone subjects[0] = "Philosophy" # changing one can't change the other. subjects subjects_clone - Copy and paste into the text window and use the debugger to step through. Show how the values are different when slicing is used. == More list practise === - Try this out in a while loop: def remove_i(text) '''Remove all instances of the letter i from the string text.''' text.count("i") while text.count("i") > 0: # while there are more i's to remove position = text.find("i") # find the next i text = text[0:position] + text[position + 1:] - Exercise with the person next to you: rewrite the function above so that it returns a new, modified string and doesn't change the original. Hint: You want to use an accumulator. == Nested Lists == - Let's create a list of student and grade info: student_grades = [['999888777', 78], ['111222333', 90], ['444555666', 83]] - We can refer to elements of the lists within the list as follows: student_grades[0] student_grades[0][0] student_grades[0][1] - Write the functions below. Step through each function in the debugger, emphasizing the order in which the values are taken in the for loops. def average_grade(grade_list): '''Return the average grade (a float) for all of the students in the list of lists grade_list, where the inner lists contain a student ID (a str) and a grade (a number).''' total_grade = 0.0 for student in grade_list: total_grade += student[1] return total_grade / len(grade_list) def get_student_IDs(grade_list): '''Return a list of strs containing the student IDs from the list of lists grade_list, where the inner lists contain a student ID (a str) and a grade (a number).''' ID_list = [] for student in grade_list: ID_list.append(student[0]) return ID_list == Nested Loops == # Print contents of a nested list for student in student_grades: print student for x in student: print x measurements = [[33, 34, 30], [29, 31, 34], [28, 27, 30]] # Print the average of each inner list for dataset in measurements: sum = 0.0 for datapoint in dataset: sum += datapoint print sum / len(dataset) # We can also use the function "sum" for dataset in measurements: print sum(dataset) / float(len(dataset)) ... but sum contains a loop. I promise! # Create a list of averages ... add "averages = []" before the loop ... change the print to an append