mutating lists (class slides)

CSc 110 - mutating lists

Announcements

  • Quiz 06 will be on next Wednesday, Apr 10 (mutate nested lists & sets)
  • Review Module 11 and 12

Lists are mutable

  • changes to a list in a function will remain after the function finishes running
  • changes to individual list elements do not change the list itself

Changing a list in a loop

Changes to individual list elements do not change the list itself

numbers = [1, 2, 1, 4, 5]
for n in numbers:
  n += 1
numbers
[1, 2, 1, 4, 5]

Use a for i in range loop instead:

numbers = [1, 2, 1, 4, 5]
for i in range(len(numbers)):
  numbers[i] += 1
numbers
[2, 3, 2, 5, 6]

Write a function

  1. Its name is square_all
  2. It takes a list of integers as argument
  3. It mutates the list, squaring each integer (n**2)
test_list = [1, 2, 3, 4]
square_all(test_list)
assert test_list == [1, 4, 9, 16]
assert square_all([-1, -2, -4]) == [1, 4, 16]

Write a function – solution

def square_all(numbers):
  for i in range(len(numbers)):
    numbers[i] = numbers[i]**2
  return numbers
    
def main():
  test_list = [1, 2, 3, 4]
  square_all(test_list)
  assert test_list == [1, 4, 9, 16]
  assert square_all([-1, -2, -4]) == [1, 4, 16]
  print(test_list) # [1, 4, 9, 16]
  
main()
[1, 4, 9, 16]

Removing elements from a list in a loop

Using a for i in range when removing items in a list throws an error

numbers = [1, 2, 1, 4, 5]
for i in range(len(numbers)):
  numbers.pop(i)
numbers

ERROR

Removing elements from a list in a loop

Use a while loop instead (remember to adjust i if doing conditional removal)

numbers = [1, 2, 1, 4, 5]
i = 0
while i < len(numbers):
  numbers.pop(i)
numbers
[]

Or go backwards

numbers = [1, 2, 1, 4, 5]
for i in range(len(numbers)-1, -1, -1):
  numbers.pop(i)
numbers
[]

Write a function

  1. Its name is remove_names
  2. It takes one argument: a list of strings
  3. It mutates and returns the argument list removing all strings that end in vowel
names = ["Beatrice", "Philip", "Anna", "Peter"]
remove_names(names)
assert names == ["Philip", "Peter"]

Write a function – solution 1

def remove_names(string_list):
  i = 0
  while i < len(string_list):
    if string_list[i][-1] in "aeiou":
      string_list.pop(i)
    else:
      i += 1
  return string_list
      
def main():
  names = ["Beatrice", "Philip", "Anna", "Peter"]
  remove_names(names)
  assert names == ["Philip", "Peter"]
  print(names) # ["Philip", "Peter"]

main()
['Philip', 'Peter']

Write a function – solution 2

def remove_names(string_list):
  for i in range(len(string_list)-1, -1, -1):
    if string_list[i][-1] in "aeiou":
      string_list.pop(i)
  return string_list
      
def main():
  names = ["Beatrice", "Philip", "Anna", "Peter"]
  remove_names(names)
  assert names == ["Philip", "Peter"]
  print(names) # ["Philip", "Peter"]

main()
['Philip', 'Peter']

Removing elements from inner lists in 2D lists

lists_of_numbers = [ [2, 3, 1, 2], [4, 5, 2, 1] ]
for inner_list in lists_of_numbers:
  for i in range(len(inner_list)-1, -1, -1):
    inner_list.pop(i)
    
print(lists_of_numbers)
[[], []]

Write a function

  1. Its name is remove_odds
  2. It takes a list of lists of integers as argument
  3. It mutates the inner list, removing odd numbers
lists_of_numbers = [ [2, 3, 1, 2], [4, 5, 2, 1] ]
remove_odds(lists_of_numbers)
assert lists_of_numbers == [ [2, 2], [4, 2] ]

Write a function – solution

def remove_odds(lists_of_numbers):
  for inner_list in lists_of_numbers:
    for i in range(len(inner_list)-1, -1, -1):
      if inner_list[i] % 2 != 0:
        inner_list.pop(i)
  return lists_of_numbers

def main():
  test_list = [ [2, 3, 1, 2], [4, 5, 2, 1] ]
  remove_odds(test_list)
  assert test_list == [ [2, 2], [4, 2] ]
  print(test_list) # [ [2, 2], [4, 2] ]
  
main()
[[2, 2], [4, 2]]

Submit code for attendance

Submit your remove_odds functions to Gradescope for attendance.

Name your file remove_odds.py